title: Test NextJS API middleware with Jest
body: <p>I have an API route with middleware setup in NextJS like so:</p>
  
  <p><strong>/src/middleware/validateData/index.ts</strong></p>
  
  <pre><code>import { NextApiRequest, NextApiResponse } from 'next';
  import schema from './schema';
  
  type Handler = (req: NextApiRequest, res: NextApiResponse) =&gt; void;
  
  export default (handler: Handler) =&gt; {
    return (req: NextApiRequest, res: NextApiResponse) =&gt; {
      const { error } = schema.validate(req.body, { abortEarly: false });
      if (error) res.status(400).send(error);
      else handler(req, res);
    };
  };
  </code></pre>
  
  <p><strong>/src/api/foo.ts</strong></p>
  
  <pre><code>import { NextApiRequest, NextApiResponse } from 'next';
  
  import validateData from '../../middleware/validateData';
  
  const foo = (req: NextApiRequest, res: NextApiResponse) =&gt; {
    res.send('It works!');
  };
  
  export default validateData(foo);
  </code></pre>
  
  <p>The schema reference is a <code>@hapi/joi</code> schema to validate the <code>req.body</code> data and I haven't included it because I don't think it's relevant to the question.</p>
  
  <p>I'm wondering how I can unit test the middleware on it's own? This is about as far as I got:</p>
  
  <p><strong>/src/middleware/validateData/index.test.ts</strong></p>
  
  <pre><code>import validateData from './validateData';
  
  describe('validateData', () =&gt; {
    const mockHandler = jest.fn();
  
    const mockReq = {
      body: '',
    };
  
    const mockRes = {
      send: jest.fn(),
    };
  
    it('responds with error', () =&gt; {
      validateData(mockHandler)(mockReq, mockRes);
      expect(mockRes.send).toHaveBeenCalled();
    });
  });
  </code></pre>
  
  <p>But with this technique I firstly get type errors that <code>mockReq</code> and <code>mockRes</code> are missing properties (so I guess I need to mock those correctly but not sure how), and secondly the test fails because <code>res.send</code> is not called despite invalid body data being passed.</p>
  
  <p>Anyone know how to mock and test this correctly?</p>
  
  <p>I feel like my approach is totally wrong because I want to inspect the entire response (status code, specific message received and so on). Is the only approach to spin up a mock server and actually mock an api call or something?</p>