การสอดแนมฟังก์ชัน node.js ที่ไม่ได้ส่งออกโดยใช้การล้อเล่นไม่ทำงานตามที่คาดไว้

ฉันกำลังพยายามเยาะเย้ยฟังก์ชันที่ไม่ได้ส่งออกผ่าน '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, () => {

        });
    });
})

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