【问题标题】:Spying on a non-exported node.js function using jest not working as expected使用 jest 监视未导出的 node.js 函数未按预期工作
【发布时间】:2019-06-04 12:57:44
【问题描述】:

我正在尝试通过“jest”和“re-wire”模拟非导出函数。

在这里我试图模拟“iAmBatman”(没有双关语),但它没有被导出。

所以我使用 rewire,它做得很好。 但是 jest.mock 并没有按预期工作。

我在这里遗漏了什么还是有一种简单的方法可以达到同样的效果?

jest给出的错误信息是:

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, () => {

        });
    });
})

【问题讨论】:

    标签: javascript node.js unit-testing jestjs


    【解决方案1】:

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

    jest.spyOn(object, methodName)
    

    这解释了你的错误:你没有给函数name,而是函数本身。 在这种情况下,使用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.

    【讨论】:

      猜你喜欢
      • 2018-06-19
      • 1970-01-01
      • 2018-02-01
      • 2019-10-30
      • 2015-04-11
      • 2022-01-25
      • 2019-12-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多