जैस्मीन के साथ निजी तरीकों के लिए कोणीय / टाइपस्क्रिप्ट के लिए इकाई परीक्षण कैसे लिखें


196

आप कोणीय 2 में एक निजी फ़ंक्शन का परीक्षण कैसे करते हैं?

class FooBar {

    private _status: number;

    constructor( private foo : Bar ) {
        this.initFooBar();

    }

    private initFooBar(){
        this.foo.bar( "data" );
        this._status = this.fooo.foo();
    }

    public get status(){
        return this._status;
    }

}

इसका हल मुझे मिल गया

  1. बाहरी के दायरे में मौजूदा वस्तुओं पर स्थानीय चर का संदर्भ स्टोर बंद करने वाले क्लोजर के अंदर ही टेस्ट कोड डालें या कोड जोड़ें।

    बाद में एक उपकरण का उपयोग करके परीक्षण कोड को हटा दें। http://philipwalton.com/articles/how-to-unit-test-private-functions-in-javascript/

कृपया मुझे इस समस्या को हल करने का एक बेहतर तरीका सुझाएं यदि आपने कोई किया है?

पुनश्च

  1. इस तरह के प्रश्न के अधिकांश उत्तर जैसे कि यह समस्या का समाधान नहीं देता है, इसीलिए मैं यह प्रश्न पूछ रहा हूं

  2. अधिकांश डेवलपर कहते हैं कि आप निजी कार्यों का परीक्षण नहीं करते हैं, लेकिन मैं नहीं कहता कि वे गलत हैं या सही हैं, लेकिन मेरे मामले के लिए निजी परीक्षण करने की आवश्यकताएं हैं।


11
परीक्षण केवल सार्वजनिक इंटरफ़ेस का परीक्षण करना चाहिए, न कि निजी कार्यान्वयन का। आपके द्वारा सार्वजनिक इंटरफ़ेस पर किए गए परीक्षण निजी भाग को भी कवर करते हैं।
टॉस्क

16
मुझे पसंद है कि आधे उत्तर वास्तव में कैसे होने चाहिए। ओपी सवाल पूछता है, आप एक्स कैसे हैं? स्वीकृत उत्तर वास्तव में आपको बताता है कि एक्स कैसे करना है। फिर बाकी के सभी घूमते हैं और कहते हैं, न केवल मैं आपको एक्स (जो स्पष्ट रूप से संभव है) बताएगा, लेकिन आपको वाई करना चाहिए। अधिकांश यूनिट परीक्षण उपकरण (मैं नहीं हूं यहाँ केवल जावास्क्रिप्ट के बारे में बात करना) निजी कार्यों / विधियों का परीक्षण करने में सक्षम है। मैं समझाता हूं कि जेएस भूमि में खो जाने के कारण ऐसा क्यों लगता है (जाहिर है, आधे उत्तर दिए गए हैं)।
क्वाटर्नियन

13
प्रबंधनीय कार्यों में किसी समस्या को तोड़ने के लिए यह अच्छा प्रोग्रामिंग अभ्यास है, इसलिए "foo (x: type)" फ़ंक्शन को निजी फ़ंक्शन a (x: type), b (x: type), c (y: other_type) और d कहेंगे z: yet_another_type)। अब क्योंकि फू, कॉल का प्रबंधन कर रहा है और सामान को एक साथ रख रहा है, यह एक प्रकार की अशांति पैदा करता है, जैसे एक धारा में चट्टानों के पीछे के किनारे, छाया जो वास्तव में सभी श्रेणियों का परीक्षण सुनिश्चित करने के लिए कठिन हैं। इस तरह यह सुनिश्चित करना आसान है कि प्रत्येक श्रेणी का उप-समूह मान्य है, यदि आप माता-पिता "फू" का परीक्षण करने का प्रयास करते हैं, तो अकेले रेंज परीक्षण मामलों में बहुत जटिल हो जाता है ।
क्वाटर्नियन

18
यह कहना नहीं है कि आप सार्वजनिक इंटरफ़ेस का परीक्षण नहीं करते हैं, जाहिर है आप करते हैं, लेकिन निजी तरीकों का परीक्षण करने से आपको लघु प्रबंधनीय श्रृंखला की एक श्रृंखला का परीक्षण करने की अनुमति मिलती है (उसी कारण आपने उन्हें पहले स्थान पर लिखा था, आप पूर्ववत क्यों करेंगे जब यह परीक्षण की बात आती है), और सिर्फ इसलिए कि सार्वजनिक इंटरफेस पर परीक्षण वैध हैं (शायद कॉलिंग फ़ंक्शन इनपुट रेंज को प्रतिबंधित करता है) का मतलब यह नहीं है कि जब आप अधिक उन्नत तर्क जोड़ते हैं और उन्हें दूसरे से कॉल करते हैं तो निजी तरीके त्रुटिपूर्ण नहीं होते हैं नई माता पिता काम करता है,
Quaternion

5
यदि आपने उन्हें ठीक से टीडीडी के साथ परीक्षण किया है, तो आप यह पता लगाने की कोशिश कर रहे हैं कि आप बाद में क्या कर रहे थे, जब आपको उन्हें सही तरीके से परीक्षण करना चाहिए था।
क्वाटर्नियन

जवाबों:


343

मैं आपके साथ हूं, भले ही यह "केवल यूनिट को सार्वजनिक एपीआई का परीक्षण करने के लिए" एक अच्छा लक्ष्य है, ऐसे समय होते हैं जब यह सरल नहीं लगता है और आपको लगता है कि आप एपीआई या इकाई-परीक्षणों में समझौता करने के बीच चयन कर रहे हैं। आप यह पहले से ही जानते हैं, क्योंकि आप जो करने के लिए कह रहे हैं, ठीक है, इसलिए मैं इसमें नहीं जाऊंगा। :)

टाइपस्क्रिप्ट में मैंने कुछ तरीकों की खोज की है जो आप यूनिट-परीक्षण के लिए निजी सदस्यों तक पहुंच सकते हैं। इस वर्ग पर विचार करें:

class MyThing {

    private _name:string;
    private _count:number;

    constructor() {
        this.init("Test", 123);
    }

    private init(name:string, count:number){
        this._name = name;
        this._count = count;
    }

    public get name(){ return this._name; }

    public get count(){ return this._count; }

}

भले ही वर्ग के सदस्यों को टीएस सम्बन्धी सीमाओं का उपयोग कर private, protected, public, संकलित जे एस कोई निजी सदस्यों, के बाद से इस जे एस में एक बात नहीं है। यह विशुद्ध रूप से टीएस संकलक के लिए उपयोग किया जाता है। वजह:

  1. anyएक्सेस प्रतिबंध के बारे में चेतावनी देने से आप कंपाइलर से बच सकते हैं और बच सकते हैं:

    (thing as any)._name = "Unit Test";
    (thing as any)._count = 123;
    (thing as any).init("Unit Test", 123);

    इस दृष्टिकोण के साथ समस्या यह है कि संकलक को बस यह पता नहीं है कि आप क्या कर रहे हैं any, इसलिए आपको वांछित प्रकार की त्रुटियां नहीं मिलती हैं:

    (thing as any)._name = 123; // wrong, but no error
    (thing as any)._count = "Unit Test"; // wrong, but no error
    (thing as any).init(0, "123"); // wrong, but no error

    यह स्पष्ट रूप से रिफैक्टिंग को और कठिन बना देगा।

  2. आप []निजी सदस्यों को प्राप्त करने के लिए ऐरे एक्सेस ( ) का उपयोग कर सकते हैं :

    thing["_name"] = "Unit Test";
    thing["_count"] = 123;
    thing["init"]("Unit Test", 123);

    हालांकि यह कायरतापूर्ण लगता है, TSC वास्तव में प्रकारों को मान्य करेगा जैसे कि आपने उन्हें सीधे एक्सेस किया था:

    thing["_name"] = 123; // type error
    thing["_count"] = "Unit Test"; // type error
    thing["init"](0, "123"); // argument error

    सच कहूँ तो मुझे नहीं पता कि यह क्यों काम करता है। यह स्पष्ट रूप से एक जानबूझकर "एस्केप हैच" है जो आपको बिना सुरक्षा खोने के निजी सदस्यों तक पहुंच प्रदान करता है। यह वही है जो मुझे लगता है कि आप अपनी इकाई-परीक्षण के लिए चाहते हैं।

यहां टाइपस्क्रिप्ट प्लेग्राउंड में एक कार्यशील उदाहरण दिया गया है

टाइपस्क्रिप्ट 2.6 के लिए संपादित करें

एक अन्य विकल्प जो कुछ का उपयोग करने के लिए है // @ts-ignore( टीएस 2.6 में जोड़ा गया है ) जो निम्नलिखित पंक्ति में सभी त्रुटियों को दबाता है:

// @ts-ignore
thing._name = "Unit Test";

इसके साथ समस्या यह है कि, यह निम्न पंक्ति की सभी त्रुटियों को दबा देता है:

// @ts-ignore
thing._name(123).this.should.NOT.beAllowed("but it is") = window / {};

मैं व्यक्तिगत रूप से @ts-ignoreएक कोड-गंध पर विचार करता हूं , और जैसा कि डॉक्स कहते हैं:

हम आपको बहुत ही संयम से इस टिप्पणी का उपयोग करने की सलाह देते हैं । [जोर मूल]


45
इतना अच्छा है कि आप मानक इकाई परीक्षक हठधर्मिता के बजाय वास्तविक समाधान के साथ इकाई परीक्षण पर एक यथार्थवादी रुख सुनें।
d512

2
व्यवहार के कुछ "आधिकारिक" स्पष्टीकरण (जो एक उपयोग के मामले के रूप में इकाई परीक्षण का भी हवाला देते हैं): github.com/microsoft/TypeScript/issues/19335
हारून बाइल

1
बस नीचे बताए अनुसार `// @ ts-ign` का उपयोग करें। लिंटर को निजी एक्सेसर को नजरअंदाज करने के लिए कहना
टॉमसो

1
@ टॉमसो हाँ, यह एक और विकल्प है, लेकिन इसका उपयोग करने का एक ही नुकसान है as any: आप सभी प्रकार की जाँच खो देते हैं।
हारून बेयेल

2
सबसे अच्छा जवाब मैंने थोड़ी देर में देखा है, धन्यवाद @AaronBeall। और यह भी, मूल प्रश्न पूछने के लिए धन्यवाद tymspy।
निकोलस.ब्लैंक

26

आप निजी तरीकों को कॉल कर सकते हैं । यदि आपको निम्न त्रुटि का सामना करना पड़ा है:

expect(new FooBar(/*...*/).initFooBar()).toEqual(/*...*/);
// TS2341: Property 'initFooBar' is private and only accessible within class 'FooBar'

बस उपयोग करें // @ts-ignore:

// @ts-ignore
expect(new FooBar(/*...*/).initFooBar()).toEqual(/*...*/);

यह सबसे ऊपर होना चाहिए!
5

2
यह निश्चित रूप से एक और विकल्प है। यह उसी मुद्दे से ग्रस्त as anyहै जिसमें आप किसी भी प्रकार की जाँच को खो देते हैं, वास्तव में आप पूरी लाइन पर किसी भी प्रकार की जाँच को खो देते हैं।
हारून बीलल

19

जैसा कि अधिकांश डेवलपर्स निजी फ़ंक्शन का परीक्षण करने की अनुशंसा नहीं करते हैं , यह परीक्षण क्यों नहीं करते हैं ?.

उदाहरण के लिए।

YourClass.ts

export class FooBar {
  private _status: number;

  constructor( private foo : Bar ) {
    this.initFooBar({});
  }

  private initFooBar(data){
    this.foo.bar( data );
    this._status = this.foo.foo();
  }
}

TestYourClass.spec.ts

describe("Testing foo bar for status being set", function() {

...

//Variable with type any
let fooBar;

fooBar = new FooBar();

...
//Method 1
//Now this will be visible
fooBar.initFooBar();

//Method 2
//This doesn't require variable with any type
fooBar['initFooBar'](); 
...
}

@Aaron, @ टिहरी टेम्पलियर को धन्यवाद।


1
मुझे लगता है कि जब आप किसी निजी / संरक्षित पद्धति को कॉल करने का प्रयास करते हैं तो टाइपस्क्रिप्ट लाइनिंग में त्रुटि देता है।
गुडगिप

1
@ गुडगाइप यह टाइप एरर देगा और कंपाइल नहीं करेगा। :)
tatspy

10

निजी तरीकों के लिए परीक्षण न लिखें। यह इकाई परीक्षणों के बिंदु को पराजित करता है।

  • आपको अपनी कक्षा के सार्वजनिक एपीआई का परीक्षण करना चाहिए
  • आपको अपनी कक्षा के निहितार्थ विवरण का परीक्षण नहीं करना चाहिए

उदाहरण

class SomeClass {

  public addNumber(a: number, b: number) {
      return a + b;
  }
}

इस पद्धति के लिए परीक्षण को बदलने की आवश्यकता नहीं है यदि बाद में कार्यान्वयन में परिवर्तन होता है, लेकिन behaviourसार्वजनिक एपीआई की स्थिति समान रहती है।

class SomeClass {

  public addNumber(a: number, b: number) {
      return this.add(a, b);
  }

  private add(a: number, b: number) {
       return a + b;
  }
}

सिर्फ उनका परीक्षण करने के लिए तरीकों और गुणों को सार्वजनिक न करें। इसका आमतौर पर मतलब है कि या तो:

  1. आप API (सार्वजनिक इंटरफ़ेस) के बजाय कार्यान्वयन का परीक्षण करने का प्रयास कर रहे हैं।
  2. परीक्षण को आसान बनाने के लिए आपको तर्क को उसकी अपनी कक्षा में स्थानांतरित करना चाहिए।

3
शायद इस पर टिप्पणी करने से पहले पोस्ट पढ़ें। मैं स्पष्ट रूप से बताता हूं कि परीक्षण निजीकरण व्यवहार के बजाय परीक्षण कार्यान्वयन की गंध है, जो नाजुक परीक्षणों की ओर जाता है।
मार्टिन

1
एक ऐसी वस्तु की कल्पना करें जो आपको 0 और निजी संपत्ति x के बीच एक यादृच्छिक संख्या प्रदान करती है। यदि आप जानना चाहते हैं कि क्या एक्स को सही ढंग से सेट किया गया है, तो यह जांचने के लिए एक्स के मूल्य का परीक्षण करना बहुत आसान है कि क्या आपके पास सही संख्या में हैं या नहीं।
गलदोर

1
@ user3725805 यह कार्यान्वयन के परीक्षण का एक उदाहरण है, न कि व्यवहार का। यह अलग करना बेहतर होगा जहां निजी नंबर आता है: एक निरंतर, एक विन्यास, निर्माता - और वहां से परीक्षण करें। यदि निजी किसी अन्य स्रोत से नहीं आता है, तो यह "मैजिक नंबर" एंटीपैटर्न में आता है।
मार्टिन

1
और इसे कार्यान्वयन का परीक्षण करने की अनुमति क्यों नहीं है? अप्रत्याशित परिवर्तनों का पता लगाने के लिए यूनिट परीक्षण अच्छे हैं। जब किसी कारण से कंस्ट्रक्टर नंबर सेट करना भूल जाता है, तो परीक्षण तुरंत विफल हो जाता है और मुझे चेतावनी देता है। जब कोई कार्यान्वयन को बदलता है तो परीक्षण भी विफल हो जाता है, लेकिन मैं एक परीक्षण को अपनाने की तुलना में अनिर्धारित त्रुटि को प्राथमिकता देता हूं।
गलडोर

2
+1। बहुत बढ़िया जवाब। @TimJames सही अभ्यास बताना या त्रुटिपूर्ण दृष्टिकोण को इंगित करना एसओ का बहुत उद्देश्य है। ओपी जो चाहे हासिल करने के लिए हैक-नाजुक तरीका खोजने के बजाय।
सैयद अकील आशिक

4

"निजी तरीकों का परीक्षण न करें" की बात वास्तव में किसी का उपयोग करने वाले की तरह वर्ग का परीक्षण है

यदि आपके पास 5 तरीकों के साथ एक सार्वजनिक एपीआई है, तो आपके वर्ग का कोई भी उपभोक्ता इनका उपयोग कर सकता है, और इसलिए आपको उनका परीक्षण करना चाहिए। एक उपभोक्ता को आपकी कक्षा के निजी तरीकों / गुणों का उपयोग नहीं करना चाहिए, जिसका अर्थ है कि आप निजी सदस्यों को बदल सकते हैं जब सार्वजनिक उजागर कार्यक्षमता समान रहती है।


यदि आप आंतरिक एक्स्टेंसिबल कार्यक्षमता पर निर्भर हैं, के protectedबजाय का उपयोग करें private
ध्यान दें कि protectedअभी भी एक सार्वजनिक एपीआई (!) है , बस अलग तरह से उपयोग किया जाता है।

class OverlyComplicatedCalculator {
    public add(...numbers: number[]): number {
        return this.calculate((a, b) => a + b, numbers);
    }
    // can't be used or tested via ".calculate()", but it is still part of your public API!
    protected calculate(operation, operands) {
        let result = operands[0];
        for (let i = 1; i < operands.length; operands++) {
            result = operation(result, operands[i]);
        }
        return result;
    }
}

यूनिट टेस्ट प्रोटेक्टेड प्रॉपर्टीज को उसी तरह से इस्तेमाल करते हैं, जैसे उपभोक्ता उन्हें उप-लिंकिंग के जरिए इस्तेमाल करते हैं:

it('should be extensible via calculate()', () => {
    class TestCalculator extends OverlyComplicatedCalculator {
        public testWithArrays(array: any[]): any[] {
            const concat = (a, b) => [].concat(a, b);
            // tests the protected method
            return this.calculate(concat, array);
        }
    }
    let testCalc = new TestCalculator();
    let result = testCalc.testWithArrays([1, 'two', 3]);
    expect(result).toEqual([1, 'two', 3]);
});

3

यह मेरे लिए काम किया:

के बजाय:

sut.myPrivateMethod();

यह:

sut['myPrivateMethod']();

2

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

सबसे पहले - जब हम इकाई परीक्षण के दौरान एक कक्षा में निजी सदस्यों के लिए खुद की जरूरत महसूस करते हैं, तो यह आम तौर पर एक बड़ा, मोटा लाल झंडा होता है जिसे हमने अपने रणनीतिक या सामरिक दृष्टिकोण में जाना है और अनजाने में धक्का देकर एकल जिम्मेदारी वाले प्रिंसिपल का उल्लंघन किया है व्यवहार जहां यह नहीं है। उन तरीकों तक पहुंचने की आवश्यकता महसूस करना जो वास्तव में एक निर्माण प्रक्रिया के एक अलग-थलग सबरूटीन से ज्यादा कुछ नहीं हैं, यह सबसे आम घटनाओं में से एक है; हालाँकि, यह आपके बॉस की तरह है जो आपसे काम के लिए तैयार रहने की उम्मीद करता है और आपको यह जानने की भी ज़रूरत होती है कि सुबह की दिनचर्या आपको किस अवस्था में ले जाती है ...

ऐसा होने का दूसरा सबसे आम उदाहरण है जब आप खुद को लौकिक "देव वर्ग" का परीक्षण करने की कोशिश करते हुए पाते हैं। यह अपने आप में एक विशेष प्रकार की समस्या है, लेकिन एक प्रक्रिया के अंतरंग विवरणों को जानने की आवश्यकता के साथ एक ही मूल मुद्दे से ग्रस्त है - लेकिन यह विषय बंद हो रहा है।

इस विशिष्ट उदाहरण में, हमने प्रभावी रूप से बार ऑब्जेक्ट को FooBar क्लास के कंस्ट्रक्टर के लिए प्रारंभिक रूप से आरम्भ करने की जिम्मेदारी सौंपी है। ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग में, कोर टेंट में से एक यह है कि कंस्ट्रक्टर "पवित्र" है और इसे अमान्य डेटा के खिलाफ संरक्षित किया जाना चाहिए जो अपने स्वयं के आंतरिक स्थिति को अमान्य कर देगा और इसे डाउनस्ट्रीम में कहीं और विफल करने के लिए प्राइमेड छोड़ देगा (क्या बहुत गहरा हो सकता है पाइप लाइन।)

हम यहां ऐसा करने में विफल रहे हैं कि FooBar ऑब्जेक्ट को एक बार स्वीकार करने के लिए अनुमति देता है जो कि FooBar के निर्माण के समय तैयार नहीं है, और मामलों को अपने आप में लेने के लिए FooBar ऑब्जेक्ट को "हैकिंग" के द्वारा मुआवजा दिया है। हाथ।

यह ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग (बार के मामले में) के एक और दसवें हिस्से का पालन करने में विफलता का परिणाम है, जो यह है कि किसी वस्तु की स्थिति को पूरी तरह से प्रारंभिक किया जाना चाहिए और निर्माण के तुरंत बाद अपने 'सार्वजनिक सदस्यों के लिए किसी भी आने वाली कॉल को संभालने के लिए तैयार होना चाहिए। अब, इसका मतलब यह नहीं है कि निर्माणकर्ता को सभी उदाहरणों में बुलाया जाता है। जब आपके पास एक ऐसी वस्तु होती है जिसमें कई जटिल निर्माण परिदृश्य होते हैं, तो अपने वैकल्पिक सदस्यों को किसी ऐसी वस्तु के लिए व्यवस्थित करना बेहतर होता है जो किसी रचना डिज़ाइन-पैटर्न (फैक्टरी, बिल्डर, आदि ...) के अनुसार लागू की जाती है। उत्तरार्द्ध मामले,

आपके उदाहरण में, बार की "स्थिति" संपत्ति एक वैध स्थिति में नहीं लगती है जिसमें एक FooBar इसे स्वीकार कर सकता है - इसलिए FooBar उस मुद्दे को सही करने के लिए कुछ करता है।

दूसरा मुद्दा जो मैं देख रहा हूं वह यह है कि ऐसा प्रतीत होता है कि आप अभ्यास परीक्षण-संचालित विकास के बजाय अपने कोड का परीक्षण करने की कोशिश कर रहे हैं। निश्चित रूप से इस समय मेरी अपनी राय है; लेकिन, इस प्रकार का परीक्षण वास्तव में एक विरोधी पैटर्न है। आप जो कर रहे हैं वह यह महसूस करने के फंदे में पड़ रहा है कि आपको कोर डिज़ाइन की समस्याएं हैं जो आपके कोड को इस तथ्य के बाद परीक्षण करने से रोकती हैं, न कि आपके द्वारा आवश्यक परीक्षणों को लिखने और बाद में परीक्षणों को प्रोग्रामिंग करने के बजाय। किसी भी तरह से आप समस्या पर आते हैं, आपको अभी भी एक ही संख्या के परीक्षणों और कोड की पंक्तियों के साथ समाप्त करना चाहिए जो आपने वास्तव में एक ठोस कार्यान्वयन प्राप्त किया था। इसलिए - जब आप अपने विकास के प्रयासों की शुरुआत में केवल मामले को संबोधित कर सकते हैं, तो परीक्षण योग्य कोड में अपने तरीके से रिवर्स इंजीनियर की कोशिश क्यों करें?

अगर आपने ऐसा किया होता, तो आपको बहुत पहले ही इस बात का अहसास हो जाता था कि आपको अपने डिजाइन के खिलाफ परीक्षण करने के लिए कुछ बल्कि icky कोड लिखना होगा और कार्यान्वयन के लिए व्यवहार को शिफ्ट करके अपने दृष्टिकोण को फिर से शुरू करने का अवसर होगा आसानी से परीक्षण करने योग्य हैं।


2

मैं @toskv से सहमत हूं: मैं ऐसा करने की सलाह नहीं दूंगा :-)

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

उदाहरण के लिए:

export class FooBar {
  private _status: number;

  constructor( private foo : Bar ) {
    this.initFooBar({});
  }

  private initFooBar(data){
    this.foo.bar( data );
    this._status = this.foo.foo();
  }
}

में स्थानांतरित किया जाएगा:

(function(System) {(function(__moduleName){System.register([], function(exports_1, context_1) {
  "use strict";
  var __moduleName = context_1 && context_1.id;
  var FooBar;
  return {
    setters:[],
    execute: function() {
      FooBar = (function () {
        function FooBar(foo) {
          this.foo = foo;
          this.initFooBar({});
        }
        FooBar.prototype.initFooBar = function (data) {
          this.foo.bar(data);
          this._status = this.foo.foo();
        };
        return FooBar;
      }());
      exports_1("FooBar", FooBar);
    }
  }
})(System);

: इस plunkr देखें https://plnkr.co/edit/calJCF?p=preview


1

जैसा कि कई पहले ही बता चुके हैं, जितना आप निजी तरीकों का परीक्षण करना चाहते हैं, उसे आपके लिए काम करने के लिए अपने कोड या ट्रांसपिलर को हैक नहीं करना चाहिए। आधुनिक दिन टाइपस्क्रिप्ट उन सभी हैक्स को नकार देगा जो लोगों ने अब तक प्रदान किए हैं।


उपाय

TLDR ; यदि किसी विधि का परीक्षण किया जाना चाहिए, तो आपको एक वर्ग में कोड को डिकूपिंग करना चाहिए जिसे आप परीक्षण किए जाने के लिए सार्वजनिक होने की विधि को उजागर कर सकते हैं।

आपके पास विधि निजी होने का कारण यह है कि कार्यक्षमता आवश्यक रूप से उस वर्ग द्वारा उजागर नहीं की जाती है, और इसलिए यदि कार्यक्षमता वहां नहीं है, तो इसे अपने वर्ग में डिकॉय किया जाना चाहिए।

उदाहरण

मैंने इस लेख को चलाया जो यह समझाने का एक बड़ा काम करता है कि आपको निजी विधियों के परीक्षण से कैसे निपटना चाहिए। यहां तक ​​कि कुछ तरीकों को भी शामिल किया गया है और वे क्यों खराब कार्यान्वयन हैं।

https://patrickdesjardins.com/blog/how-to-unit-test-private-method-in-typescript-part-2

नोट : इस कोड को ऊपर दिए गए ब्लॉग से हटा दिया गया है (मैं लिंक बदलने के पीछे की सामग्री के मामले में नकल कर रहा हूं)

इससे पहले
class User{
    public getUserInformationToDisplay(){
        //...
        this.getUserAddress();
        //...
    }

    private getUserAddress(){
        //...
        this.formatStreet();
        //...
    }
    private formatStreet(){
        //...
    }
}
उपरांत
class User{
    private address:Address;
    public getUserInformationToDisplay(){
        //...
        address.getUserAddress();
        //...
    }
}
class Address{
    private format: StreetFormatter;
    public format(){
        //...
        format.ToString();
        //...
    }
}
class StreetFormatter{
    public toString(){
        // ...
    }
}

1

वर्ग कोष्ठक का उपयोग करके निजी विधि को कॉल करें

Ts फ़ाइल

class Calculate{
  private total;
  private add(a: number) {
      return a + total;
  }
}

spect.ts फ़ाइल

it('should return 5 if input 3 and 2', () => {
    component['total'] = 2;
    let result = component['add'](3);
    expect(result).toEqual(5);
});

0

हारून द्वारा जवाब सबसे अच्छा है और मेरे लिए काम कर रहा है :) मैं इसे वोट करूंगा लेकिन दुख की बात है कि मैं (लापता प्रतिष्ठा) नहीं कर सकता।

मेरा कहना है कि निजी तरीकों का परीक्षण करना ही उनका उपयोग करने का एकमात्र तरीका है और दूसरी तरफ साफ कोड है।

उदाहरण के लिए:

class Something {
  save(){
    const data = this.getAllUserData()
    if (this.validate(data))
      this.sendRequest(data)
  }
  private getAllUserData () {...}
  private validate(data) {...}
  private sendRequest(data) {...}
}

यह इन सभी तरीकों को एक बार में परीक्षण नहीं करने के लिए बहुत मायने रखता है क्योंकि हमें उन निजी तरीकों का मजाक उड़ाना होगा, जिन्हें हम बाहर नहीं निकाल सकते क्योंकि हम उन्हें एक्सेस नहीं कर सकते। इसका मतलब यह है कि हमें एक पूरे के रूप में परीक्षण करने के लिए एक इकाई परीक्षण के लिए बहुत सारे कॉन्फ़िगरेशन की आवश्यकता है।

इसने कहा कि सभी आश्रितों के साथ उपरोक्त विधि का परीक्षण करने का सबसे अच्छा तरीका अंत परीक्षा है, क्योंकि यहां एक एकीकरण परीक्षण की आवश्यकता है, लेकिन यदि आप TDD (टेस्ट ड्रिवेन डेवलपमेंट) का अभ्यास कर रहे हैं, तो E2E परीक्षण आपकी मदद नहीं करेगा, लेकिन परीक्षण कोई भी तरीका होगा


0

यह मार्ग जो मैं ले जाता हूं वह वह है जहां मैं कक्षा के बाहर कार्य करता हूं और अपनी निजी पद्धति को कार्य सौंपता हूं।

export class MyClass {
  private _myPrivateFunction = someFunctionThatCanBeTested;
}

function someFunctionThatCanBeTested() {
  //This Is Testable
}

अब मुझे नहीं पता कि मैं किस प्रकार के ओओपी नियम तोड़ रहा हूं, लेकिन सवाल का जवाब देने के लिए, यह है कि मैं निजी तरीकों का परीक्षण कैसे करता हूं। मैं इस के पेशेवरों और विपक्ष पर सलाह देने के लिए किसी का भी स्वागत करता हूं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.