【问题标题】:How do I reset mocked values in Jest?如何在 Jest 中重置模拟值?
【发布时间】:2020-10-24 15:43:37
【问题描述】:

我正在尝试开玩笑并编写单元测试。 我已经为几个函数编写了单元测试。这些函数使用从不同文件导入的常量对象。所以我模拟了这些常量。

describe('testing helpers', () => {

    beforeEach(() => jest.resetModules());

    describe('reset board', () => {
        // first test using original constant values
        test('with default constants', () => {
            const game = {
                board: [
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0]
                ],
                count: 0
            };

            const helper = require('./helper');
            expect(helper.resetBoard()).toEqual(game);
        });

        // second test using mocked constant values
        test('reset board', () => {
            const game = {
                board: [
                    [0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0]
                ],
                count: 0
            };  

            jest.mock("./constants", () => ({ ROWS: 4, COLUMNS: 5 }));

            const helper = require('./helper');
            expect(helper.resetBoard()).toEqual(game);
        });
    });

    describe('make move', () => {
        // third test with original constant values
        test('player 1 move', () => {

            const testBoard = [
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0]
                ];
            const testTurn = 'YELLOW';
            const testColumn = 0;

            const expectedBoard = [
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0],
                    [1, 0, 0, 0, 0, 0, 0]
                ];

            const helper = require('./helper');
            helper.makeMove(testBoard, testTurn, testColumn);
            expect(testBoard).toEqual(expectedBoard);
        });
    });
});

但是当第二个描述块中的第三个测试运行时,它会选择模拟值而不是原始值。我认为这个beforeEach(() => jest.resetModules()); 会重置模拟值,但它不起作用。 请帮助解决这个问题。 任何其他改进测试的提示将不胜感激。

【问题讨论】:

标签: javascript unit-testing jestjs mocking


【解决方案1】:

jest.resetModules 只重置模块缓存并允许重新导入模块,它不会影响模块模拟:

重置模块注册表 - 所有必需模块的缓存。这对于隔离测试之间本地状态可能发生冲突的模块很有用。

为了丢弃模块模拟,需要使用jest.unmockjest.dontMock。如果这些测试的默认行为未模拟constants,则可以是:

beforeEach(() => {
  jest.unmock("./constants");
  jest.resetModules();
});

在这种情况下,在顶层导入原始实现并在需要它的测试中使用它会更容易:

const helper = require('./helper');
...

require 仅在需要模拟实现 helper 或它所依赖的模块 (constants) 的测试中模拟。 beforeEachjest.resetModulesjest.unmock 仍然是可取的,以便这些测试不会相互交叉污染,使用顶级 helper 的测试不会受到它的影响。

【讨论】:

    【解决方案2】:

    这可以解决。

    describe('testing helpers', () => {
        beforeEach(() => jest.clearAllMocks());
        ....
    })
    

    如果使用jest + @testing-library/react

    import { cleanup } from '@testing-library/react'
    
    beforeEach(cleanup)
    

    【讨论】:

    • 这不会改变任何东西。 describe 的层次结构影响了 before* 和 after* 测试影响测试。由于所有测试共享一个共同的描述块,beforeEach 会影响所有测试。
    • 仅适用于 Jest 间谍,不适用于模块模拟。 OP中的所有测试都调用jest.resetModules(),应该没有问题。我很确定问题出在我发布的内容上。
    猜你喜欢
    • 2018-09-04
    • 2015-06-25
    • 2020-10-02
    • 2021-06-09
    • 1970-01-01
    • 2021-11-02
    • 2019-12-26
    • 2021-08-20
    • 2018-11-18
    相关资源
    最近更新 更多