我正在尝试使用返回 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
的 automock 创建的 mock 类方法的返回值?
我已经尝试使用 mockReturnValueOnce()
等。
最佳答案
jest.mock
在这种情况下,你真的不需要自动模拟整个 common
模块,因为你只是替换一个方法的实现,所以 jest.mock('./../common');
不是必需的。
Common.getConfig
getConfig
是一个 prototype method所以 getConfig
存在于 Common
的 prototype 上。要模拟它,请使用 Common.prototype.getConfig
而不是 Common.getConfig
。
在 fileUnderTest.js 中配置
Common
的一个实例被创建并且 config
被设置为调用 common.getConfig()
的结果fileUnderTest
运行,这在需要时立即发生,因此 Common.prototype.getConfig
的 mock 必须到位在你调用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'
})
})
重置模块是必要的,因为一旦需要一个模块,它就会被添加到模块缓存中,并且每次需要时都会返回同一个模块,除非模块被重置。
关于javascript - 在逐个测试的基础上开 Jest 模拟类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55190252/