2014-12-05 6 views
48

मैं ECMAScript 6 webpack + Traceur का उपयोग कर ES5 CommonJS को transpile करने के लिए मॉड्यूल के साथ बेला की कोशिश कर रहा हूँ, लेकिन मैं उन्हें सफलतापूर्वक परीक्षण में समस्या हो रही इकाई।ES6 मॉड्यूल के साथ इकाई परीक्षण के लिए निर्भरता नकली कैसे

मैंने जेस्ट + ट्रेसेर प्रीप्रोसेसर का उपयोग करने की कोशिश की, लेकिन ऑटोमोकिंग और निर्भरता नाम खराब हो रहे हैं, और मुझे जेस्ट और नोड-इंस्पेक्टर डीबगिंग के साथ काम करने के लिए स्रोत मैप्स नहीं मिल रहे हैं।

क्या यूनिट परीक्षण ES6 मॉड्यूल के लिए एक बेहतर ढांचा है?

+2

मैं Traceur के बारे में पता नहीं है (यह एक अच्छा तरीका है), लेकिन [6to5] (http://6to5.github.io/) हंसी के साथ अच्छी तरह से काम करता है और है (वे अच्छे बांध कर रहे हैं) एक [6to5-हंसी प्लगइन] (https://github.com/6to5/6to5-jest)। –

+0

धन्यवाद जेम्स, मैं इसे देख लूंगा।यह 6to5 पारदर्शी दिखने के लिए अधिक मानव-पठनीय है और मुझे आवश्यक सभी ES6 सुविधाओं को शामिल करता है, इसलिए शायद मैं उस मार्ग पर जाऊंगा। –

+0

इसके अलावा, क्या आप डीबग करने के लिए नोड-इंस्पेक्टर का उपयोग करके जेस्ट के साथ स्रोत मैप्स प्राप्त करने में सक्षम थे? –

उत्तर

5

मैं वास्तव में इस जेस्ट छोड़ने और कर्मा + जैस्मीन + Webpack के साथ जा रहा है और आप Webpack से rewire inject-loader है एक छोटे से अधिक लचीलापन है कि एक और विकल्प का उपयोग कर रहे हैं, तो निर्भरता

+1

कार्यों के अंदर चर को रिवायर द्वारा बदला नहीं जा सकता है। यह जावास्क्रिप्ट द्वारा बाधित है और इसे रिवायर द्वारा अवरुद्ध नहीं किया जा सकता है। –

6

उपहास करने के लिए https://github.com/jhnns/rewire का उपयोग करके काम करने के लिए मिला है।

उदाहरण के लिए, एक परीक्षण Webpack साथ आ जाते हैं कि में:

describe('when an alert is dismissed',() => { 

    // Override Alert as we need to mock dependencies for these tests 
    let Alert, mockPubSub 

    beforeEach(() => { 
    mockPubSub = {} 
    Alert = require('inject!./alert')({ 
     'pubsub-js': mockPubSub 
    }).Alert 
    }) 

    it('should publish \'app.clearalerts\'',() => { 
    mockPubSub.publish = jasmine.createSpy() 
    [...] 
    expect(mockPubSub.publish).toHaveBeenCalled() 
    }) 
}) 

इंजेक्षन-लोडर, एक समान तरीके से कम से कम proxyquire करने के लिए एक rewire में जबकि आयात करने आप पहली बार आयात करने से पहले निर्भरता इंजेक्षन करने की अनुमति देता है और फिर रिवायर करें जो कुछ घटकों का मज़ाक उड़ाता है (उदाहरण के लिए जिनके पास कुछ प्रारंभिकता है) असंभव है।

+0

हां, लेकिन यह केवल तब काम करता है जब आप 'आवश्यकता' के बजाय 'आयात' का उपयोग करते हैं .. as ..'syntax – alwe

+0

सत्य नहीं है। मैं इसे ES6 आयात वाक्यविन्यास के साथ सफलतापूर्वक उपयोग करता हूं। यह आपके सेटअप पर निर्भर करता है मुझे लगता है लेकिन मैं बेबेल-लोडर के साथ बेबेल का उपयोग कर रहा हूं। यह 'आवश्यकता 'और ईएस 6 आयात दोनों के लिए काम करता है। परीक्षण में निर्भरता का मज़ाक उड़ाने के लिए केवल एक ही जगह की आवश्यकता है। – djskinner

+0

हाय @djskinner। मैं इंजेक्शन-लोडर को बेबेल, वेबपैक और करम के साथ जाने की कोशिश कर रहा हूं लेकिन परेशानी हो रही है। क्या आप अपने उत्तर में 'karma.config.js' (और' webpack.config' फ़ाइल जोड़कर) जोड़ना चाहते हैं। अग्रिम में धन्यवाद। –

39

मैंने अपने परीक्षणों के भीतर import * as obj शैली को नियोजित करना शुरू कर दिया है, जो किसी ऑब्जेक्ट के गुणों के रूप में मॉड्यूल से सभी निर्यात आयात करता है जिसे बाद में मजाक किया जा सकता है। मुझे यह रिवायर या प्रॉक्सीक्वायर या किसी भी समान तकनीक जैसी चीज़ों का उपयोग करने से बहुत साफ करने वाला लगता है।

मैं ट्रेसूर के लिए बात नहीं कर सकता जो कि प्रश्न में इस्तेमाल किया गया ढांचा था, लेकिन मुझे यह कर्म, जैस्मीन और बेबेल के अपने सेटअप के साथ काम करने के लिए मिला है, और मैं इसे यहां पोस्ट कर रहा हूं जैसा कि ऐसा लगता है इस प्रकार का सबसे लोकप्रिय सवाल बनें।

मैंने Redux क्रियाओं को नकल करने की आवश्यकता होने पर अक्सर इस रणनीति का उपयोग किया है। यहाँ एक छोटी उदाहरण है:

import * as exports from 'module-you-want-to-mock'; 
import SystemUnderTest from 'module-that-uses-above-module'; 

describe('your module',() => { 
    beforeEach(() => { 
    spyOn(exports, 'someNamedExport'); // mock a named export 
    spyOn(exports, 'default');   // mock the default export 
    }); 
    // ... now the above functions are mocked 
}); 
+1

इस पैटर्न या तकनीक को बेहतर तरीके से दस्तावेज किया जाना चाहिए क्योंकि यह es6 mock तीसरे पक्ष निर्भरताओं पर भरोसा करने के बजाय मॉड्यूल। मुझे यह देखने में दिलचस्पी होगी क्योंकि एएस 6 अधिक मुख्यधारा बन जाता है कि यूनिट परीक्षण के संबंध में, यह पैटर्न उदाहरणों में अधिक बार देखा जाता है जब 'मॉड्यूल' नोटेशन से 'आयात {someExport} का उपयोग करने के बजाय मॉड्यूल आयात करते समय। – markyph

+0

चूंकि आपने रेडक्स क्रियाओं का उल्लेख किया है, इसलिए यह इंगित करने योग्य है कि जब किसी कार्य को किसी कनेक्टेड घटक से बंधे होते हैं तो उसे ध्यान देना होगा। उन कार्यों के लिए जासूसों को लागू करना जो पहले ही बाध्य हैं, का कोई प्रभाव नहीं पड़ता है। प्रतिक्रिया-रेडक्स के कनेक्ट() फ़ंक्शन को कॉल करने के विभिन्न तरीकों को समझना मेरे दिमाग को खोए बिना काम करने में मेरे लिए महत्वपूर्ण था: https://github.com/reactjs/react-redux/blob/master/docs/api.md # connectmapstatetoprops-mapdispatchtoprops-mergeprops-options – killthrush

+1

आप एक-दूसरे में खून बहने से परीक्षण कैसे करते हैं? यह मेरा अनुभव रहा है कि आयात का मज़ाक उड़ाते हुए बाद में वास्तविक उदाहरण के बजाय नकली का उपयोग करने के लिए परीक्षण करता है, या इसके विपरीत। – user831865

4

हाय आप proxyquire इस्तेमाल कर सकते हैं:

import assert from 'assert'; 
import sinon from 'sinon'; 
import Proxyquire from 'proxyquire'; 

let proxyquire = Proxyquire.noCallThru(), 
    pathModelLoader = './model_loader'; 

describe('ModelLoader module.',() => { 
    it('Should load all models.',() => { 
     let fs, modelLoader, ModelLoader, spy, path; 
     fs = { 
      readdirSync(path) { 
       return ['user.js']; 
      } 
     }; 
     path = { 
      parse(data) { 
       return {name: 'user'}; 
      } 
     }; 
     ModelLoader = proxyquire(pathModelLoader, {'fs': fs, 'path': path}); 
     modelLoader = new ModelLoader.default(); 
     spy = sinon.spy(modelLoader, 'loadModels'); 
     modelLoader.loadModels(); 
     assert(spy.called); 
    }); 
}); 
1

Proxyquire मदद मिलेगी, लेकिन ऐसा नहीं होने वाला, आधुनिक webpack + ES6 मॉड्यूल के साथ काम करने के लिए यानी "अन्य नामों"।

import fs from 'fs'; 
import reducers from 'core/reducers'; 
... 
proxyquire('../module1', { 
    'fs': mockFs, // this gonna work 
    'core/reducers': mockReducers // what about this? 
}); 

that काम नहीं करेगा। जब तक आप FS नकली कर सकते हैं - आप reducers नकली नहीं कर सकते। आपको किसी भी वेबपैक या बेबेल रूपांतरण के बाद real निर्भरता का नाम निर्दिष्ट करना होगा। आम तौर पर - नाम सापेक्ष स्थान module1 करने के लिए। हो सकता है '../../../shared/core/reducers'। शायद नहीं।

वहाँ समाधान में गिरावट है - https://github.com/theKashey/proxyquire-webpack-alias (स्थिर, proxyquire का कांटा के आधार पर) या https://github.com/theKashey/resolveQuire (कम स्थिर, मूल proxyquire पर चलाया जा सकता है)

उन दोनों के रूप में अच्छी तरह से काम करता है, और किसी भी ES6 मॉड्यूल नकली होगा एक proxyquire तरह से

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