简体   繁体   English

开玩笑的单次导入模拟模块

[英]Jest mock module for single import

When using jest with ES6 modules and babel-jest , all the jest.mock calls are hoisted . 当将jest与ES6模块和babel-jest ,所有jest.mock调用都将被挂起
Let's say I'd like to mock fs module for the tested class, but preserve the original implementation for the rest of the modules (for example some utils that I use during the test). 假设我想为测试的类模拟fs模块,但保留其余模块的原始实现(例如,我在测试期间使用的一些utils)。
Consider the following example: 考虑以下示例:

class UnderTest {
  someFunction(){
    fs.existsSync('blah');
  }
}

class TestUtility {
  someOtherFunction(){
    fs.existsSync('blahblah');
  }
}

the test: 考试:

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' 
})

Now, one would expect that with the following approach the fs module will be mocked for UnderTest but not for TestUtility . 现在,可以期望通过以下方法模拟fs模块以用于UnderTest而不是TestUtility

import {TestUtility} from './test-utility';

jest.mock('fs');

import {UnderTest } from './under-test';

However, due to the hoisting, fs module will be mocked for all the modules (which is undesirable). 但是,由于吊装,将对所有模块模拟fs模块(这是不希望的)。

Is there any way to achieve the described behavior? 有什么办法可以实现所描述的行为?

To opt out from mocking a module in a test jest.doMock(moduleName, factory, options) and jest.dontMock(moduleName) should be used. 为了避免在测试中嘲笑模块,应该使用jest.doMock(moduleName, factory, options)jest.dontMock(moduleName)

jest.doMock(moduleName, factory, options) jest.doMock(moduleName,factory,options)

When using babel-jest , calls to mock will automatically be hoisted to the top of the code block. 使用babel-jest ,对mock调用将自动提升到代码块的顶部。 Use this method if you want to explicitly avoid this behavior. 如果要明确避免此行为,请使用此方法。

jest.dontMock(moduleName) jest.dontMock(模块名称)

When using babel-jest , calls to unmock will automatically be hoisted to the top of the code block. 使用babel-jest ,对unmock调用将自动提升到代码块的顶部。 Use this method if you want to explicitly avoid this behavior. 如果要明确避免此行为,请使用此方法。

So in your case I would try something like 所以在您的情况下,我会尝试类似

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' 
})

You should probably use jest's requireActual : 您可能应该使用笑话的requireActual

const fs = jest.requireActual('fs'); // Unmockable version of jest 

class TestUtility {
  someOtherFunction(){
    fs.existsSync('blahblah');
  }
}

From the documentation : 文档中

Jest allows you to mock out whole modules in your tests, which can be useful for testing your code is calling functions from that module correctly. Jest允许您模拟测试中的整个模块,这对于测试代码是否正确地从该模块调用函数很有用。 However, sometimes you may want to use parts of a mocked module in your test file, in which case you want to access the original implementation, rather than a mocked version. 但是,有时您可能想在测试文件中使用模拟模块的一部分,在这种情况下,您要访问原始实现,而不是模拟版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM