2017-05-03 12 views
8

का उपयोग करके es6 कक्षा का नकल कैसे करें I jest का उपयोग करके Mailer कक्षा का नकल करने का प्रयास कर रहा हूं और मैं यह नहीं समझ सकता कि इसे कैसे किया जाए। दस्तावेज़ यह कैसे काम करता है के कई उदाहरण नहीं देते हैं। प्रक्रिया यह है कि मेरे पास एक नोड इवेंट password-reset होगा जिसे निकाल दिया गया है और जब उस ईवेंट को निकाल दिया जाता है, तो मैं Mailer.send(to, subject, body) का उपयोग करके एक ईमेल भेजना चाहता हूं।जेस्ट

project_root 
-- __test__ 
---- server 
------ services 
-------- emails 
---------- mailer.test.js 
-- server 
---- services 
------ emails 
-------- mailer.js 
-------- __mocks__ 
---------- mailer.js 

यहाँ मेरी नकली फ़ाइल __mocks__/mailer.js है: यहाँ मेरी निर्देशिका संरचना है

const Mailer = jest.genMockFromModule('Mailer'); 

function send(to, subject, body) { 
    return { to, subject, body }; 
} 

module.exports = Mailer; 

और मेरे mailer.test.js

const EventEmitter = require('events'); 
const Mailer = jest.mock('../../../../server/services/emails/mailer'); 

test('sends an email when the password-reset event is fired',() => { 
    const send = Mailer.send(); 
    const event = new EventEmitter(); 
    event.emit('password-reset'); 
    expect(send).toHaveBeenCalled(); 
}); 

और अंत में मेरी mailer.js वर्ग:

class Mailer { 

    constructor() { 
    this.mailgun = require('mailgun-js')({ 
     apiKey: process.env.MAILGUN_API_KEY, 
     domain: process.env.MAILGUN_DOMAIN, 
    }); 
    } 

    send(to, subject, body) { 
    return new Promise((reject, resolve) => { 
     this.mailgun.messages().send({ 
     from: 'Securely App <[email protected]>', 
     to, 
     subject: subject, 
     html: body, 
     }, (error, body) => { 
     if (error) { 
      return reject(error); 
     } 

     return resolve('The email was sent successfully!'); 
     }); 
    }); 
    } 

} 

module.exports = new Mailer(); 

तो, जेस्ट का उपयोग करके, मैं इस कक्षा का सफलतापूर्वक नकल और परीक्षण कैसे करूं? मदद के लिए बहुत धन्यवाद!

उत्तर

13

आपको अपने मेलर क्लास को मॉक करने की आवश्यकता नहीं है लेकिन mailgun-js मॉड्यूल। तो मेलगुन एक ऐसा फ़ंक्शन है जो फ़ंक्शन messages देता है जो फ़ंक्शन send देता है। तो नकली इस तरह दिखेगा।

खुश पथ

const happyPath =() => ({ 
    messages:() => ({ 
    send: (args, callback) => callback() 
    }) 
}) 

त्रुटि मामले

const errorCase =() => ({ 
    messages:() => ({ 
    send: (args, callback) => callback('someError') 
    }) 
}) 

के लिए के लिए

आप इस 2 मामलों में यह भावना अपने परीक्षण के अंदर मॉड्यूल उपहास करने के लिए बनाने के लिए है के रूप में। सबसे पहले आपको इसे एक साधारण जासूस के साथ नकल करना होगा जहां हम बाद में हमारे मामलों के लिए कार्यान्वयन सेट कर सकते हैं और फिर हमें मॉड्यूल आयात करना होगा।

jest.mock('mailgun-js', jest.fn()) 
import mailgun from 'mailgun-js' 
import Mailer from '../../../../server/services/emails/mailer' 

अपने मॉड्यूल के रूप में वादा किया है कि हम 2 विकल्प या तो परीक्षण से वादा वापसी या async/await का उपयोग किया है का उपयोग करता है। मैं बाद में एक और जानकारी के लिए उपयोग करता हूं here देखें।

test('test the happy path', async() => { 
//mock the mailgun so it returns our happy path mock 
    mailgun.mockImplementation(() => happyPath) 
    //we need to use async/awit here to let jest recognize the promise 
    const send = await Mailer.send(); 
    expect(send).toBe('The email was sent successfully!') 
}); 

आप परीक्षण करने के लिए सही पैरामीटर आप इस तरह नकली अनुकूलित करने की आवश्यकता के साथ कि mailgun send विधि बुलाया गया था चाहते हैं:

const send = jest.fn((args, callback) => callback()) 
const happyPath =() => ({ 
    messages:() => ({ 
    send: send 
    }) 
}) 

अब आप की जांच कर सकता है कि भेजने के लिए पहले पैरामीटर सही था:

expect(send.mock.calls[0][0]).toMatchSnapshot() 
+0

मैं घर पाने और इसे आजमाने की प्रतीक्षा नहीं कर सकता। सुपर-महान स्पष्टीकरण के लिए बहुत बहुत धन्यवाद। – dericcain

3

बस Googlers और भविष्य के आगंतुकों के लिए, यहां मैंने ES6 कक्षाओं के लिए जेस्ट मॉकिंग सेट अप किया है। मेरे पास working example at github भी है, ईएस मॉड्यूल सिंटैक्स को पार करने के लिए बेबेल-जेस्ट के साथ ताकि जेस्ट उन्हें ठीक से मॉक कर सके।

__mocks __/MockedClass.js

const stub = { 
    someMethod: jest.fn(), 
    someAttribute: true 
} 

module.exports =() => stub; 

आपका कोड नए के साथ इस फोन कर सकते हैं, और अपने परीक्षण में आप फ़ंक्शन को कॉल करें और किसी भी डिफ़ॉल्ट कार्यान्वयन के ऊपर लिख सकते हैं।

example.spec।जेएस

const mockedClass = require("path/to/MockedClass")(); 
const AnotherClass = require("path/to/AnotherClass"); 
let anotherClass; 

jest.mock("path/to/MockedClass"); 

describe("AnotherClass",() => { 
    beforeEach(() => { 
    mockedClass.someMethod.mockImplementation(() => { 
     return { "foo": "bar" }; 
    }); 

    anotherClass = new AnotherClass(); 
    }); 

    describe("on init",() => { 
    beforeEach(() => { 
     anotherClass.init(); 
    }); 

    it("uses a mock",() => { 
     expect(mockedClass.someMethod.toHaveBeenCalled(); 
     expect(anotherClass.settings) 
     .toEqual(expect.objectContaining({ "foo": "bar" })); 
    }); 
    }); 

}); 
+0

मेरे लिए काम नहीं कर रहा है। 'mockedClass.someMethod'' अपरिभाषित' है। जेस्ट 21.2.1 का उपयोग करना। – stone

+0

"पथ/से/आपका क्लास" क्या है? कोड में दिखाई देने वाले एकमात्र क्लिप हैं: mockedClass और AnotherClass। मुझे लगता है कि यह "पथ/से/मॉक क्लास" होना चाहिए, क्या मैं सही हूँ? –

+1

@ पैकेट ट्रासर आप सही हैं! मैंने कोड उदाहरण अपडेट किया है। –

संबंधित मुद्दे