笑话间谍.mockImplementation调用实际方法



我有一个中间件功能:

// 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' });
}
}

在我的测试中,我做了以下操作:

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();
});
});

然而,这调用原始的verifyUser函数,而不是我添加的。

但是,如果我将这个添加到测试文件中,那么我的测试通过了:

jest.mock('../../middlewares/auth.middleware', () => ({
verifyUser: jest.fn((req, _res, next) => {
req.user = {
id: '1',
email: 'user1@email.com',
fullName: null
};
next();
}),
}));

我如何使我的代码工作,以便我可以更改每个测试的实现?

如果你看这个笑话。你可以在sppy文档中看到:

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);

这就解释了为什么添加mock可以使测试通过。

根据您正在运行的jest版本,您现在可以使用一个非常有用的辅助方法,jest.mock:

jest.mocked<T>(item: T, deep = false)

你可以:

  1. 添加mockImplementation到您的spyOn:
const spy = jest.spyOn(middleware, 'verifyUser').mockImplementation(jest.fn((req, _res, next) => {
req.user = {
id: '1',
email: 'user1@email.com',
fullName: null
};
next();
});
// ...
  1. 完全删除spyOn并重构如下:
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,
});
// ...

但是这两种方法是等价的。

最新更新