I have an API route with middleware setup in NextJS like so:
/src/middleware/validateData/index.ts
import { NextApiRequest, NextApiResponse } from 'next';
import schema from './schema';
type Handler = (req: NextApiRequest, res: NextApiResponse) => void;
export default (handler: Handler) => {
return (req: NextApiRequest, res: NextApiResponse) => {
const { error } = schema.validate(req.body, { abortEarly: false });
if (error) res.status(400).send(error);
else handler(req, res);
};
};
/src/api/foo.ts
import { NextApiRequest, NextApiResponse } from 'next';
import validateData from '../../middleware/validateData';
const foo = (req: NextApiRequest, res: NextApiResponse) => {
res.send('It works!');
};
export default validateData(foo);
The schema reference is a @hapi/joi
schema to validate the req.body
data and I haven't included it because I don't think it's relevant to the question.
I'm wondering how I can unit test the middleware on it's own? This is about as far as I got:
/src/middleware/validateData/index.test.ts
import validateData from './validateData';
describe('validateData', () => {
const mockHandler = jest.fn();
const mockReq = {
body: '',
};
const mockRes = {
send: jest.fn(),
};
it('responds with error', () => {
validateData(mockHandler)(mockReq, mockRes);
expect(mockRes.send).toHaveBeenCalled();
});
});
But with this technique I firstly get type errors that mockReq
and mockRes
are missing properties (so I guess I need to mock those correctly but not sure how), and secondly the test fails because res.send
is not called despite invalid body data being passed.
Anyone know how to mock and test this correctly?
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?