【问题标题】:Mocking require statements with Jest用 Jest 模拟 require 语句
【发布时间】:2017-08-01 10:44:26
【问题描述】:

sum.js

module.exports = function sum(a, b){
    return a + b;
};

Thing.js

var sum = require("./sum");

module.exports = class Thing {
    add(a, b){
        return sum(a, b);
    }
}

Thing.test.js

test('1 + 2 = 3', () => {
    //Arrange
    var Thing = require('./Thing');
    var thing = new Thing();

    //Act
    var result = thing.add(1, 2);

    //Assert
    expect(result).toBe(3);
});

test('sum mocked', () => {
    //Arrange
    jest.mock('./sum', () => {
        return jest.fn(() => 42);
    });

    var Thing = require('./Thing');
    var thing = new Thing();

    //Act
    var result = thing.add(1, 2);

    //Assert
    expect(result).toBe(42);
});

如何在测试时模拟 sum 'require' 依赖项?我收到以下错误。

sum mocked

    expect(received).toBe(expected)

    Expected value to be (using ===):
      42
    Received:
      3

有趣的是,如果我使用 .only 单独运行每个测试,它们都可以单独运行。

过去我使用 proxyquire 来做这样的事情,但如果可能的话我想避免它。

【问题讨论】:

    标签: javascript unit-testing jestjs


    【解决方案1】:

    取自 Jest Docs。

    beforeEach(() => {
      jest.resetModules();
    });
    
    test('moduleName 1', () => {
      jest.doMock('../moduleName', () => {
        return jest.fn(() => 1);
      });
      const moduleName = require('../moduleName');
      expect(moduleName()).toEqual(1);
    });
    
    test('moduleName 2', () => {
      jest.doMock('../moduleName', () => {
        return jest.fn(() => 2);
      });
      const moduleName = require('../moduleName');
      expect(moduleName()).toEqual(2);
    });
    

    https://facebook.github.io/jest/docs/en/jest-object.html#jestdomockmodulename-factory-options

    【讨论】:

      【解决方案2】:

      我感觉模拟每个测试文件都有效。不要问我为什么¯\_(ツ)_/¯

      对我来说最有效的方法是这样设置测试:

      // sum.test.js
      //Arrange
      const sum = require('./sum');
      
      test('1 + 2 = 3', () => {
          //Act
          const result = sum(1, 2);
      
          //Assert
          expect(result).toBe(3);
      });
      

      还有:

      // Thing.test.js
      //Arrange
      const Thing = require('./Thing');
      
      // jest.mock are hoisted so you can keep imports/require on top
      const sumSpy = jest.fn(() => 42);
      jest.mock('./sum', () => sumSpy);
      
      test('Thing', () => {
          const thing = new Thing();
      
          //Act
          const result = thing.add(1, 2);
      
          //Assert
          expect(sumSpy).toHaveBeenCalledTimes(1);
          expect(result).toBe(42);
      });
      

      您甚至可以为每个测试提供不同的模拟实现,例如:

      sumSpy.mockImplementation(() => NaN);
      

      【讨论】:

        【解决方案3】:

        在测试中,我添加了

        beforeEach(() =>  {
            jest.resetModules();
        });
        

        并且测试按预期通过。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-14
          • 2021-09-14
          • 2020-04-21
          • 2019-09-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多