我正在为一个项目编写集成测试。在一个测试套件中,我在多个测试中调用注册端点。大多数时候,我想测试给定某些 req
参数后 registerUser
函数的实际响应是什么。
这一切都工作正常,除了我还想测试 registerUser
函数抛出错误时会发生什么。我知道我可以在测试套件之上模拟 registerUser
函数,但这会影响所有测试。我尝试使用 jest.mock
和 jest.spyOn
但我还无法让它工作。
如何模拟一次 registerUser
函数的响应并在之后恢复它,这样它就不会影响套件中的其他测试?
authController.js
router.post('/register', async (req, res) => {
try {
const response = await registerUser(req);
res.status(HttpStatus.OK).json({ response });
} catch (err) {
res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ err });
}
});
authController.test.js
const faker = require('faker');
const HttpStatus = require('http-status-codes');
const authService = require('../services/authService');
// -- Tests where the response of the registerUser function are not mocked are here -- //
it('Gives a status code 500 when an unexpected error is thrown', async () => {
const registerUserMock = jest.spyOn(authService, "registerUser");
registerUserMock.mockReturnValue(() => new Error('Oh snap! Something went wrong.'));
const res = await agent.post('/register')
.send({
email: faker.internet.email(),
firstname: faker.name.firstName(),
lastname: faker.name.lastName(),
password: '123',
reTypedPassword: '123',
});
expect(res.statusCode).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
registerUserMock.mockRestore();
});
// -- more tests -- //
最佳答案
最简单的方法是
- 将应在套件中使用相同模拟响应的测试分组(描述)
- 模拟该套件的
beforeAll
Hook 中的响应并保存模拟实例 - 恢复该套件的
afterAll
Hook 中的原始实现。
describe('tests with successful auth result', () => {
let authSpy;
beforeAll(() => {
authSpy = jest.spyOn(authService, "registerUser").mockReturnValue(...);
});
afterAll(() => {
authSpy.mockRestore();
});
// tests using successful result
});
describe('tests with failing auth result', () => {
// same but with different spy result
});
注意两件重要的事情:
- 您需要对从
mockReturnValue
返回的模拟实例调用mockRestore
,而不是初始 spy 值 - 最好在
beforeEach
/beforeAll
中设置模拟并在afterEach
/afterAll
中恢复它,因为如果您直接在测试中设置和恢复它(it
),那么如果测试失败,spy 仍然无法恢复,并且可能会影响后续测试!
关于node.js - 如何在测试套件中仅模拟一次函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63768068/