更改 class 上的笑话模拟以进行单次测试

Change jest mock on class for single test

我有一个问题,我想在测试不同模块时更改单个测试的 class 方法 returns。我有以下内容:

testingModule.test.js

const { testingModuleMethod } = require('../testingModule')

jest.mock('../helperClass', () =>
    jest.fn().mockImplementation(() => ({
        helperClassMethod: jest.fn()
    }))
);

describe('testingModule.js', () => {

    describe('testingModuleMethod', () => {
        describe('when errors', () => {
            const consoleSpy = jest.spyOn(console, 'error');
    
            // SOMETHING NEEDS TO GO HERE TO CHANGE THE jest.mock ON LINE 3

            await expect(testingModuleMethod(data)).rejects.toThrow('Error');
            expect(consoleSpy).toHaveBeenCalled();

            consoleSpy.mockRestore();
        });
    });
});

testingModule.js

const HelperClass = require('./helperClass');

const testingModuleMethod = async (data, callback) => {
    try {
        const objectToEvaluate = data.object;

        const helperClassInstance = new HelperClass();

        await helperClassInstance.helperClassMethod(objectToEvaluate);
        log('info', "Success!");
        callback(null, {});
    } catch(error) {
        log('error', 'Something went wrong')
    }
};

无论我在那里输入什么,我都会收到代码错误(未定义),或者它只是忽略它并由于开始时的模拟而解决。我尝试添加一个间谍以及导入 class 并使用原型覆盖。

我正在使用节点并且 "jest": "^27.0.6"

我通过执行以下操作设法回答了这个问题:

首先我发现要像这样模拟 class 我必须像这样在模拟中添加一个玩笑函数:

    describe('testingModuleMethod', () => {
        describe('when errors', () => {
            const consoleSpy = jest.spyOn(console, 'error');
    
            HelperClass.mockImplementation(() => ({
                    helperClassMethod: jest.fn(() => { throw new Error('Error') })
                }));

            await expect(testingModuleMethod(data)).rejects.toThrow('Error');
            expect(consoleSpy).toHaveBeenCalled();

            consoleSpy.mockRestore();
        });
    });

这也对其余测试产生了连锁反应,所以我在开头添加了一个 beforeEach,如下所示:

        HelperClass.mockImplementation(
            jest.fn().mockImplementation(() => ({
                helperClassMethod: jest.fn()
            }))
        );

最后我需要 class。整体测试现在看起来像这样并且有效:

const { testingModuleMethod } = require('../testingModule');
const HelperClass = require('./helperClass');

jest.mock('../helperClass', () =>
    jest.fn().mockImplementation(() => ({
        helperClassMethod: jest.fn()
    }))
);

describe('testingModule.js', () => {

    beforeEach(() => {
        HelperClass.mockImplementation(
            jest.fn().mockImplementation(() => ({
                helperClassMethod: jest.fn()
            }))
        );
    });

    describe('testingModuleMethod', () => {
        describe('when errors', () => {
            const consoleSpy = jest.spyOn(console, 'error');
    
            HelperClass.mockImplementation(() => ({
                    helperClassMethod: jest.fn(() => { throw new Error('Error') })
                }));

            await expect(testingModuleMethod(data)).rejects.toThrow('Error');
            expect(consoleSpy).toHaveBeenCalled();

            consoleSpy.mockRestore();
        });
    });
});