将jest
与ES6模块和babel-jest
一起使用时,所有jest.mock
的调用都是hoisted。
假设我想为测试的类模拟fs
模块,但保留其余模块的原始实现(例如,在测试期间使用的一些utils)。
考虑以下示例:
class UnderTest {
someFunction(){
fs.existsSync('blah');
}
}
class TestUtility {
someOtherFunction(){
fs.existsSync('blahblah');
}
}
测试:
it('Should test someFunction with mocked fs while using TestUtility'', () => {
testUtility.someOtherFunction(); // Should work as expected
underTest.someFunction(); // Should work with mock implementation of 'fs'
})
现在,人们希望通过以下方法为fs
而不是UnderTest
来模拟TestUtility
模块。
import {TestUtility} from './test-utility';
jest.mock('fs');
import {UnderTest } from './under-test';
但是,由于吊装,fs
模块将针对所有模块进行模拟(这是不可取的)。
有什么办法可以实现所描述的行为?
答案 0 :(得分:2)
要选择在测试jest.doMock(moduleName, factory, options)
和jest.dontMock(moduleName)
中模拟模块,请选择退出。
jest.doMock(模块名称,工厂,选项)
使用
babel-jest
时,对mock
的调用将自动提升到代码块的顶部。如果要明确避免这种行为,请使用此方法。
jest.dontMock(moduleName)
使用
babel-jest
时,对unmock
的调用将自动提升到代码块的顶部。如果要明确避免这种行为,请使用此方法。
所以在您的情况下,我会尝试类似的方法
beforeEach(() => {
jest.resetModules();
});
it('Should test someFunction with mocked fs while using TestUtility'', () => {
jest.dontMock('fs');
testUtility.someOtherFunction(); // Should work as expected
jest.doMock('fs', () => {
return ... // return your fs mock implementation;
});
underTest.someFunction(); // Should work with mock implementation of 'fs'
})
答案 1 :(得分:0)
您可能应该使用玩笑的requireActual
:
const fs = jest.requireActual('fs'); // Unmockable version of jest
class TestUtility {
someOtherFunction(){
fs.existsSync('blahblah');
}
}
Jest允许您在测试中模拟整个模块,这对于测试代码是否正确地从该模块调用函数很有用。但是,有时您可能想在测试文件中使用模拟模块的某些部分,在这种情况下,您要访问原始实现,而不是模拟版本。