title: Mocking express and mongoose with jest in typescript
body: <p>I've been having a hard time finding good resources on how to use <code>jest.fn()</code> to mock typescript classes and methods on classes (such as express' <code>Request</code>, <code>Response</code> and <code>NextFunction</code>, and the <code>save()</code> method on a mongoose model.)</p>
  
  <p>As an example, let's say I have the following model and controller:</p>
  
  <p>models/Foo.ts:</p>
  
  <pre><code>import * as mongoose from "mongoose"
  
  export type FooModel = mongoose.Document &amp; {
    owner: mongoose.Schema.Types.ObjectId,
    bars: string[]
  }
  
  const fooSchema = new mongoose.Schema({
    owner: { type: mongoose.Schema.Types.ObjectId, ref: "User", index: true },
    bars: [String]
  }
  
  export const Foo = mongoose.model&lt;FooModel&gt;("Foo", fooSchema)
  </code></pre>
  
  <p>controllers/foo.ts:</p>
  
  <pre><code>import { Request, Response, NextFunction } from "express";
  import { Foo, FooModel } from "../models/Foo";
  
  export let createFoo = async (req: Request, res: Response, next: NextFunction) =&gt; {
    try {
      const foo = new Foo({
        owner: req.user._id,
        bars: req.body.bars
      });
      await foo.save();
      res.status(200).json(foo);
    } catch (err) {
      next(err)
    }
  }
  </code></pre>
  
  <p>And I'd like to add the some unit tests:</p>
  
  <pre><code>import { Request, Response, NextFunction } from "express";
  import { Foo } from "../../src/models/Foo";
  import * as fooController from "../../src/controllers/foo";
  import {} from "jest";
  
  describe("createFoo", async () =&gt; {
    let req: Request;
    let res: Response;
    let next: NextFunction;
    const bars = ["baz", "qux", "quux"];
  
    beforeEach(() =&gt; {
      // Mock req, res and next
      // Set req.body.bars equal to bars
      // Stub out Foo.save() so that we don't actually save to the db
    });
  
    it("should add bars to the foo", async () =&gt; {
      await fooController.createFoo(req, res, next);
      responseData = JSON.parse(res.json)
      expect(responseData.bars).toEqual(bars);
    });
  
    it("should save the foo", async () =&gt; {
      await fooController.createFoo(req, res, next);
      expect(Foo.prototype.save).toHaveBeenCalled();
    }
  
    it("should call next on error", async () =&gt; {
      const err = new Error();
      // Set up Foo.save() to throw err
      await fooController.createFoo(req, res, next);
      expect(next).toHaveBeenCalledWith(err);
    }
  });
  </code></pre>
  
  <p>The main problems I'm having are with the commented out parts: I haven't figured out how to actually mock out <code>req</code>, <code>res</code> and <code>next</code>, or how to stub out <code>Foo.save()</code> or make it throw an error. How can I accomplish this?</p>