Слежение за неэкспортируемой функцией node.js с использованием jest не работает должным образом

Я пытаюсь издеваться над неэкспортируемой функцией с помощью «шутки» и «переподключения».

Здесь я пытаюсь издеваться над «iAmBatman» (без каламбура), но он не экспортируется.

Поэтому я использую rewire, который хорошо работает. Но 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, () => {

        });
    });
})

person Rajkumar Somasundaram    schedule 04.06.2019    source источник


Ответы (1)


Не совсем понятно, какова ваша цель, но если вы посмотрите на документации jest.spyOn, вы видите, что он принимает methodName в качестве второго аргумента, а не сам метод:

jest.spyOn(object, methodName)

Это объясняет вашу ошибку: вы указали не имя функции, а саму функцию. В этом случае использование jest.spyOn(services, 'iAmBatman') не сработает, так как iAmBatman не экспортируется и, следовательно, services.iAmBatman не определено.

К счастью, вам не нужен spyOn, так как вы можете просто создать новую фиктивную функцию, а затем внедрить ее с помощью __set__ rewire следующим образом:

(обратите внимание, что я удалил неопределенный 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. См. документацию jest.mock.

person Rens Baardman    schedule 05.06.2019