2009-04-04 42 views
16

में निजी कार्यों का परीक्षण करना मैं निजी कार्यान्वयन से अपने सार्वजनिक इंटरफ़ेस को अलग करने के लिए जावास्क्रिप्ट में मॉड्यूल पैटर्न का उपयोग कर रहा हूं। मैं जो कर रहा हूं उसे सरल बनाने के लिए, मेरा कोड एक चार्ट उत्पन्न करता है। चार्ट कई भागों (axises, लेबल, साजिश, कथा, आदि) की तरह मेरे कोड दिखता है के होते हैं:जावास्क्रिप्ट

var Graph = function() { 
    var private_data; 
    function draw_legend() { ... } 
    function draw_plot() { ... } 
    function helper_func() { ... } 
    ... 

    return { 
    add_data: function(data) { 
     private_data = data; 
    }, 
    draw: function() { 
     draw_legend() 
     draw_plot() 
    } 
    } 
} 

कुछ लोगों को केवल अपनी कक्षाओं की सार्वजनिक इंटरफ़ेस है, जो समझ में आता है परीक्षण वकील, लेकिन मैं था वास्तव में प्रत्येक घटक को अलग-अलग परीक्षण करने के लिए कुछ परीक्षणों में शामिल होना पसंद है। अगर मैं अपना draw_legend() फ़ंक्शन खराब करता हूं, तो मैं उस परीक्षण को असफल करना चाहता हूं, सार्वजनिक ड्रॉ() फ़ंक्शन के लिए परीक्षण नहीं। क्या मैं यहां गलत ट्रैक पर हूं?

मैं विभिन्न वर्गों में से प्रत्येक घटक को अलग कर सकता हूं, उदाहरण के लिए एक लीजेंड क्लास बनाएं। लेकिन यह कभी-कभी कोड की 5-10 लाइनों के लिए कक्षा बनाने के लिए मूर्खतापूर्ण प्रतीत होता है, और यह बदसूरत होगा क्योंकि मुझे निजी राज्य के समूह में गुजरना होगा। और मैं अपने सहायक कार्यों का परीक्षण करने में सक्षम नहीं होगा। क्या मुझे वैसे भी ऐसा करना चाहिए? क्या मुझे इसे चूसना चाहिए और केवल सार्वजनिक ड्रॉ() का परीक्षण करना चाहिए? या क्या कोई और समाधान है?

+0

यह उपयोगी हो सकता है [कैसे जावास्क्रिप्ट में यूनिट परीक्षा निजी कार्य के लिए] (http://philipwalton.com/articles/how-to-unit-test-private-functions-in-javascript/) – amirnissim

उत्तर

9

बाहरी क्षेत्र से आंतरिक कार्यों (निजी) तक पहुंचने का कोई तरीका नहीं है। यदि आप आंतरिक कार्यों का परीक्षण करना चाहते हैं तो आप केवल परीक्षण उद्देश्यों के लिए सार्वजनिक विधि जोड़ने पर विचार कर सकते हैं। यदि आप किसी प्रकार के निर्माण वातावरण का उपयोग कर रहे हैं, उदाहरण के लिए चींटी, आप उत्पादन के लिए जावास्क्रिप्ट फ़ाइल को प्री-प्रोसेस कर सकते हैं और उन परीक्षण कार्यों को हटा सकते हैं।

वास्तव में जावास्क्रिप्ट एक ऑब्जेक्ट उन्मुख भाषा है। यह सिर्फ एक statitcally टाइप नहीं है।

+5

दरअसल, जावास्क्रिप्ट ऑब्जेक्ट उन्मुख नहीं है, यह प्रोटोटाइप-आधारित है। यह सिर्फ ओओ व्यवहार की नकल कर सकता है। – pcjuzer

+11

@pcjuzer, जावास्क्रिप्ट सबसे निश्चित रूप से ऑब्जेक्ट उन्मुख है, यह सिर्फ अलग-अलग लागू किया गया है कि शास्त्रीय ओओ भाषाएं अधिकांश लोग परिचित हैं। –

+0

सभी सुरक्षा खोए बिना आप एक परीक्षण सार्वजनिक विधि कैसे जोड़ेंगे? –

0

किसी ऑब्जेक्ट उन्मुख भाषा में, आप आम तौर पर संरक्षित विधियों का परीक्षण करते हैं, परीक्षण कक्षा कक्षा के परीक्षण से प्राप्त होती है।

बेशक, जावास्क्रिप्ट वास्तव में एक ऑब्जेक्ट उन्मुख भाषा नहीं है, और यह पैटर्न विरासत की अनुमति नहीं देता है।

मुझे लगता है कि आपको या तो अपनी विधियों को सार्वजनिक करने की आवश्यकता है, या यूनिट परीक्षण पर छोड़ दें।

+0

सी # में, एक व्युत्पन्न क्लैस अपने बेस क्लास के निजी सदस्यों तक नहीं पहुंच सकता है। क्या यह अन्य भाषाओं के साथ अलग है? –

+0

जावा में भी, एक निजी सदस्य या विधि उपclass द्वारा उपयोग नहीं किया जा सकता है। –

+0

क्षमा करें, मेरा मतलब सुरक्षित है। –

1

वास्तव में एक आसान तरीका है। आप स्क्रिप्ट को लोड करने के लिए AJAX का उपयोग कर सकते हैं और एक फ़ंक्शन इंजेक्ट कर सकते हैं जो निजी कार्यों को उजागर करता है। मेरे पास एक उदाहरण here है जो qUnit और jQuery का उपयोग करता है। लेकिन मुझे यकीन है कि इसे शुद्ध जावास्क्रिप्ट का उपयोग करके आसानी से पूरा किया जा सकता है।

+0

यह एक समस्या है यदि आप बंद-संकलित (या uglified, आदि) संस्करण इकाई-परीक्षण करना चाहते हैं। मैं केवल संकलित संस्करण का परीक्षण करता हूं - यदि संकलन के साथ कोई समस्या है, तो मुझे पता होना चाहिए। –

3

मुझे एक ही समस्या है। जिस समाधान के साथ मैं आया था वह कुछ ऐसा नहीं है जो मुझे पसंद है लेकिन यह नौकरी करता है और मुझे कोई बेहतर समाधान नहीं मिल रहा है।

function Graph() 
{ 
    this.Test = function _Test(expressionStr) { return eval(expressionStr); } 

    var private_data; 
    function draw_legend() { ... } 
    function draw_plot() { ... } 
    function helper_func() { ... } 
    ... 
} 
परीक्षण करने के लिए

:

var g = new Graph(); 
g.Test("helper_func()") == something; 
g.Test("private_data") == something2 
5

मेरे समाधान सिर्फ हैक का एक छोटा सा है।QUnit उदाहरण:

Qunit परीक्षण एचटीएमएल के शीर्ष मैं घोषणा की है पर: यदि आप

सत्यापित कर सकता

if(TEST_AVAILABLE){ 
    this.test={ 
     hasDraft:hasDraft, 
     isInterpIdIn:isInterpIdIn, 
     // other private methods 
    }; 
} 

QUnit में:

var TEST_AVAILABLE = true; 

परीक्षण योग्य कक्षा में मैं इस तरह एक टुकड़ा है

test("hello booth", function() { 
    var b = new Booth(); 
    ok(b); 
    ok(b.test); 
    ok(!b.test.hasDraft()); 
}); 
+0

यहां सुझाव के समान http://www.mikeball.us/blog/how-to-make-testable-private-functions-in-javascript – jlarson

+0

@jlarson url http://www.mikeball.us में बदल गया प्रतीत होता है/ब्लॉग/परीक्षण योग्य-निजी-तरीकों में जावास्क्रिप्ट / –

0

केवल एक ही सही विकल्प है: ते के लिए अलग-अलग बिल्ड डंक और उत्पादन

1) निशान विकास केवल भागों

/* test-code */ 
api._foo = foo 
/* end-test-code */ 

2) बाद में उन्हें ... पट्टी;)

grunt.registerTask("deploy", 
    [ 
    "concat", 
    "strip-code", 
    ... 

@philwalton सुंदर लेख लिखे हैं:

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