【问题标题】:How to mock a primitive const value using jest and restore the mock?如何使用 jest 模拟原始 const 值并恢复模拟?
【发布时间】:2020-10-22 12:56:36
【问题描述】:

所以假设我有一个名为“config.js”的文件:

export const DELAY_SECONDS = 5;

在进行测试时:

// Ignore the delay when doing the tests.
jest.mock("/path/to/config", () => ({ DELAY_SECONDS: 0 }))

但我也想测试一下原始值是否有效:

it('should work with delay', () => {
    // Use original value implicitly.
    a_function_uses_DELAY_SECONDS()
    expect(...).toBe(...)
})

我怎样才能恢复那个模拟?或者有没有更好的方法来实现模拟?

我在下面尝试了一些方法,但它们都不起作用:

it('should work with delay', () => {
    jest.unmock() // Doesn't work at all, don't even know what does this method do.
    // Use original value implicitly.
    a_function_uses_DELAY_SECONDS()
    expect(...).toBe(...)
})
it('should work with delay', () => {
    jest.mock("/path/to/config", () => ({ DELAY_SECONDS: 5 })) // Call the mock again doesn't work
    // Use original value implicitly.
    a_function_uses_DELAY_SECONDS()
    expect(...).toBe(...)
})
it('should work with delay', () => {
    const config = require("/path/to/config").default;
    config.DELAY_SECONDS = 5; // Won't work, as it is a constant, cannot modify
    // Use original value implicitly.
    a_function_uses_DELAY_SECONDS()
    expect(...).toBe(...)
})

【问题讨论】:

    标签: javascript jestjs mocking


    【解决方案1】:

    你可以使用jest.doMock(moduleName, factory, options)

    例如

    config.js:

    export const DELAY_SECONDS = 5;
    

    main.js:

    import { DELAY_SECONDS } from './config';
    
    function main() {
      return DELAY_SECONDS;
    }
    
    export { main };
    

    main.test.js:

    describe('64473533', () => {
      beforeEach(() => {
        jest.resetModules();
      });
      it('should work with delay - original', () => {
        const { main } = require('./main');
        const actual = main();
        expect(actual).toBe(5);
      });
      it('should work with delay - mocked', () => {
        jest.doMock('./config', () => ({ DELAY_SECONDS: 0 }));
        const { main } = require('./main');
        const actual = main();
        expect(actual).toBe(0);
      });
    });
    

    单元测试结果:

     PASS  src/stackoverflow/64473533/main.test.js
      64473533
        ✓ should work with delay - original (445ms)
        ✓ should work with delay - mocked (2ms)
    
    -----------|----------|----------|----------|----------|-------------------|
    File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
    -----------|----------|----------|----------|----------|-------------------|
    All files  |      100 |      100 |      100 |      100 |                   |
     config.js |      100 |      100 |      100 |      100 |                   |
     main.js   |      100 |      100 |      100 |      100 |                   |
    -----------|----------|----------|----------|----------|-------------------|
    Test Suites: 1 passed, 1 total
    Tests:       2 passed, 2 total
    Snapshots:   0 total
    Time:        3.694s
    

    【讨论】:

    • 谢谢,看起来很棒。有没有办法恢复这种进展?哦,我明白了。我可以在beforeEach 中使用doMock,并且在我想要的测试中只能使用resetModules,对吗?
    • @Sraw 最好像答案建议的那样根据需要进行模拟。并且不是每次都执行 resetModules 会使测试变得不可预测。如果您需要保留对不受 doMock 影响的原始实现的访问权限,请在顶层导入它。
    猜你喜欢
    • 2018-08-18
    • 2022-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2018-01-26
    • 2020-04-24
    相关资源
    最近更新 更多