Node.js 如何在测试套件中只模拟一次函数?

Node.js 如何在测试套件中只模拟一次函数?,node.js,mocking,jestjs,Node.js,Mocking,Jestjs,我正在为一个项目编写集成测试。在一个测试套件中,我在多个测试中调用寄存器端点。大多数情况下,我想测试给定某些req参数的registerUser函数的实际响应 这一切都很好,除了我还想测试如果registerUser函数抛出错误时会发生什么。我知道我可以在测试套件的顶部模拟registerUser函数,但这将影响所有测试。我试过玩jest.mock和jest.spyOn但是我还没能让它工作 如何模拟registerUser函数的响应一次,然后恢复它,这样就不会影响套件中的其他测试 authCon

我正在为一个项目编写集成测试。在一个测试套件中,我在多个测试中调用寄存器端点。大多数情况下,我想测试给定某些
req
参数的
registerUser
函数的实际响应

这一切都很好,除了我还想测试如果
registerUser
函数抛出错误时会发生什么。我知道我可以在测试套件的顶部模拟
registerUser
函数,但这将影响所有测试。我试过玩
jest.mock
jest.spyOn
但是我还没能让它工作

如何模拟
registerUser
函数的响应一次,然后恢复它,这样就不会影响套件中的其他测试

authController.js

authController.test.js


最简单的方法是

  • 将应在套件中使用相同模拟响应的测试分组(描述)
  • 在该套件的
    之前模拟响应
    钩住并保存模拟实例
  • 恢复该套件的
    钩子中的原始实现
  • description('验证结果成功的测试',()=>{
    让authSpy;
    以前(()=>{
    authSpy=jest.spyOn(authService,“registerUser”).mockReturnValue(…);
    });
    毕竟(()=>{
    authSpy.mockRestore();
    });
    //使用成功结果的测试
    });
    描述('验证结果失败的测试',()=>{
    //相同但结果不同
    });
    
    请注意两件重要的事情:

    • 您需要对从
      mockReturnValue
      返回的模拟实例调用
      mockRestore
      ,而不是对初始spy值调用
    • 最好在
      beforeach
      /
      beforeach
      中设置模拟,并在
      afterEach
      /
      中恢复模拟,因为如果您直接在测试中设置并恢复模拟(
      ),那么如果测试失败,间谍将保持未存储状态,并可能影响以下测试
    jest.spyOn到底有什么不起作用?您忽略了与此处相关的authService。不知道registerUser是如何定义和导入的。
    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 });
        }
    });
    
    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 -- //