【问题标题】:Jest mock module for single import用于单一导入的 Jest 模拟模块
【发布时间】:2019-04-01 02:58:21
【问题描述】:

jest 与 ES6 模块和babel-jest 一起使用时,所有的jest.mock 调用都是hoisted
假设我想为测试类模拟 fs 模块,但保留其余模块的原始实现(例如我在测试期间使用的一些实用程序)。
考虑以下示例:

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 模块将被 所有模块 模拟(这是不可取的)。

有什么方法可以实现所描述的行为?

【问题讨论】:

    标签: javascript unit-testing ecmascript-6 mocking jestjs


    【解决方案1】:

    要在测试中退出模拟模块,应使用jest.doMock(moduleName, factory, options)jest.dontMock(moduleName)

    jest.doMock(moduleName, factory, options)

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

    【讨论】:

      【解决方案2】:

      你可能应该使用开玩笑的requireActual

      const fs = jest.requireActual('fs'); // Unmockable version of jest 
      
      class TestUtility {
        someOtherFunction(){
          fs.existsSync('blahblah');
        }
      }
      

      来自documentation

      Jest 允许您在测试中模拟整个模块,这对于测试您的代码是否正确调用该模块中的函数很有用。但是,有时您可能希望在测试文件中使用模拟模块的一部分,在这种情况下,您希望访问原始实现,而不是模拟版本。

      【讨论】:

      • 它暗示 jest 框架是 TestUtility 类的唯一框架,我宁愿避免。此外,如果它不是一个测试实用程序类,而是一个我出于某种原因不想模拟的真实类,那么您的解决方案将不起作用。无论如何,谢谢你的建议。
      猜你喜欢
      • 1970-01-01
      • 2021-01-21
      • 2023-03-11
      • 2019-03-05
      • 2019-08-17
      • 1970-01-01
      • 2021-02-04
      相关资源
      最近更新 更多