使用玩笑监视未导出的node.js函数无法正常工作

时间:2019-06-04 12:57:44

标签: javascript node.js unit-testing jestjs

我正在尝试通过“玩笑”和“重新接线”模拟未导出的函数。

在这里,我尝试模拟“ iAmBatman”(无双关),但未导出。

因此,我使用重新接线,效果很好。 但是jest.mock无法正常工作。

我在这里错过了什么吗,还是有一种简单的方法来实现相同的目的?

开玩笑给出的错误消息是:

Cannot spy the property because it is not a function; undefined given instead

service.js

function iAmBatman() {
    return "Its not who I am underneath";
}

function makeACall() {
    service.someServiceCall(req => {
        iAmBatman();
    });
    return "response";
}

module.export = {
    makeACall : makeACall;
}

jest.js

const services = require('./service');
const rewire = require('rewire');
const app = rewire('./service');
const generateDeepVoice = app.__get__('iAmBatman'); 

const mockDeepVoice = jest.spyOn(services, generateDeepVoice);

mockDeepVoice.mockImplementation(_ => {
    return "But what I do that defines me";
});

describe(`....', () => {
    test('....', done => {
        services.makeACall(response, () => {

        });
    });
})

1 个答案:

答案 0 :(得分:0)

尚不完全清楚您的目标是什么,但是如果查看documentation of jest.spyOn,您会发现它以methodName作为第二个参数,而不是方法本身:

jest.spyOn(object, methodName)

这说明了您的错误:您没有给函数名称,而是给了函数本身。 在这种情况下,将无法使用jest.spyOn(services, 'iAmBatman'),因为未导出iAmBatman,因此未定义services.iAmBatman

幸运的是,您不需要spyOn,因为您可以简单地创建一个新的模拟函数,然后按如下所示通过rewire的__set__注入它:

(请注意,我在第一个文件中删除了未定义的service.someServiceCall,并修复了一些错别字和多余的内容)

// service.js

function iAmBatman() {
    return "Its not who I am underneath";
}

function makeACall() {
    return iAmBatman();
}

module.exports = {
    makeACall: makeACall
}
// service.test.js

const rewire = require('rewire');
const service = rewire('./service.js');

const mockDeepVoice = jest.fn(() => "But what I do that defines me")
service.__set__('iAmBatman', mockDeepVoice)

describe('service.js', () => {
    test('makeACall should call iAmBatman', () => {
        service.makeACall();
        expect(mockDeepVoice).toHaveBeenCalled();
    });
})

另一种选择是在单独的模块中使用iAmBatman重构代码,然后使用Jest模拟模块导入。参见documentation of jest.mock.