逐个测试地讲笑话类方法

时间:2019-03-15 20:31:03

标签: javascript unit-testing mocking jestjs

我正在尝试使用一种返回JSON的方法来模拟实用程序库类。

实际图书馆结构

module.exports = class Common() {
  getConfig() {
  return {
    real: 'data'
  }
}

正在测试的文件如下:


const Common = require('./common');
const common = new Common();
const config = common.getConfig();

...

const someFunction = function() {
  // config.real is used inside this function
}

我正在尝试模拟Common类,并为每个Jest测试返回不同的配置JSON。

const fileUnderTest = require('./../fileUnderTest.js');
const Common = require('./../common.js');
jest.mock('./../common.js');

describe('something', () => {
  it('test one', () => {
    Common.getConfig = jest.fn().mockImplementation(() => {
      return {
        real : 'fake' // This should be returned for test one
      };
    });

    fileUnderTest.someFunction(); //config.real is undefined at this point
  });

  it('test two', () => {
  Common.getConfig = jest.fn().mockImplementation(() => {
      return {
        real : 'fake2' // This should be returned for test two
      };
    });
  })
})

是否可以通过测试文件顶部的common.js自动模拟创建的模拟类方法设置返回值?

我尝试使用mockReturnValueOnce()等。

1 个答案:

答案 0 :(得分:1)

jest.mock

在这种情况下,您实际上并不需要自动模拟整个common模块,因为您只是替换一种方法的实现,因此jest.mock('./../common');是不必要的。

Common.getConfig

getConfigprototype method,所以getConfig存在于Common原型上。要模拟它,请使用Common.prototype.getConfig而不是Common.getConfig

config in fileUnderTest.js

创建Common的实例,并将config设置为在common.getConfig()运行后立即调用fileUnderTest 的结果 在需要时尽快 ,因此必须在调用Common.prototype.getConfig之前使用require('./../fileUnderTest')的模拟程序。


const Common = require('./../common');
Common.prototype.getConfig = jest.fn().mockImplementation(() => ({ real: 'fake' }));
const fileUnderTest = require('./../fileUnderTest');

describe('something', () => {
  it('should test something', () => {
    fileUnderTest.someFunction();  // config.real is 'fake' at this point
  });
});

更新

要针对这样的代码对config.real进行不同的模拟 ,需要类似测试的modules be reset

describe('something', () => {
  afterEach(() => {
    jest.resetModules();  // reset modules after each test
  })

  it('test one', () => {
    const Common = require('./../common');
    Common.prototype.getConfig = jest.fn().mockImplementation(() => ({ real: 'fake' }));
    const fileUnderTest = require('./../fileUnderTest');
    fileUnderTest.someFunction();  // config.real is 'fake'
  });

  it('test two', () => {
    const Common = require('./../common');    
    Common.prototype.getConfig = jest.fn().mockImplementation(() => ({ real: 'fake2' }));
    const fileUnderTest = require('./../fileUnderTest');
    fileUnderTest.someFunction();  // config.real is 'fake2'
  })
})

重置模块是必要的,因为一旦需要一个模块,它将被添加到模块缓存中,并且除非重置模块,否则每次都需要返回相同的模块。