I have a middleware function:
// middlewares/auth.middleware.ts
export async function verifyUser(
req: Request,
res: Response,
next: NextFunction
): Promise<void> {
try {
// verify token logic
req.user = user; // I add the verified user details to req
next();
} catch (error) {
console.log(error);
res
.status(401)
.json({ error: 'You are not authorized to make this request' });
}
}
In my test, I'm doing the following:
import * as middleware from '../../middlewares/auth.middleware';
const spy = jest.spyOn(middleware, 'verifyUser');
describe('POST /api/users', () => {
test('when the user has ONLY been created in external auth', async () => {
spy.mockImplementation(
jest.fn(async (req, _res, next) => {
req.user = {
id: '1',
email: 'user1@email.com',
fullName: null,
};
next();
})
);
const res = await request(app)
.post('/api/users')
.send({ fullName: 'Jimmy Neutron' });
expect(res.status).toEqual(200);
spy.mockRestore();
});
});
However this calls the original verifyUser function, instead of the what I added.
But, if I add this to the test file then my test passes:
jest.mock('../../middlewares/auth.middleware', () => ({
verifyUser: jest.fn((req, _res, next) => {
req.user = {
id: '1',
email: 'user1@email.com',
fullName: null
};
next();
}),
}));
How can I make my code work so that I can change the implementation per test?
If you look at the jest.spyOn docs you can see this:
Note: By default, jest.spyOn also calls the spied method. This is different behavior from most other test libraries. If you want to overwrite the original function, you can use jest.spyOn(object, methodName).mockImplementation(() => customImplementation) or object[methodName] = jest.fn(() => customImplementation);
So this explains why adding a mock makes your tests pass.
Depending on what version of jest you are running, there is a very useful helper method that you can now use, jest.mocked :
jest.mocked<T>(item: T, deep = false)
In your case you could:
mockImplementation
to your spyOn
:const spy = jest.spyOn(middleware, 'verifyUser').mockImplementation(jest.fn((req, _res, next) => {
req.user = {
id: '1',
email: 'user1@email.com',
fullName: null
};
next();
});
// ...
spyOn
entirely and refactor as follows:import * as middleware from '../../middlewares/auth.middleware';
jest.mock('../../middlewares/auth.middleware');
const mockMiddleware = jest.mocked(middleware);
const mockVerifyUser = jest.fn(async (req, _res, next) => {
req.user = {
id: '1',
email: 'user1@email.com',
fullName: null,
};
next();
});
describe('POST /api/users', () => {
test('when the user has ONLY been created in external auth', async () => {
mockMiddleware.mockImplementation(() => ({
verifyUser: mockVerifyUser,
});
// ...
But the two approaches are equivalent.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.