9

चलो कहते हैं कि मैं एक घटक है कि एक सेवा समारोह का सदस्य बनता है दो:परीक्षण त्रुटि मामले

export class Component { 

    ... 

    ngOnInit() { 
     this.service.doStuff().subscribe(
      (data: IData) => { 
       doThings(data); 
      }, 
      (error: Error) => console.error(error) 
     ); 
    }; 
}; 

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

enter image description here

मैं, console.error समारोह पर जासूसी एक त्रुटि फेंक और फिर जासूसी करने के लिए बुलाया गया है उम्मीद की कोशिश की है, लेकिन वह करता है काफी यह नहीं।

मेरे इकाई परीक्षण:

spyOn(console,'error').and.callThrough(); 

serviceStub = { 
     doStuff: jasmine.createSpy('doStuff').and.returnValue(Observable.of(data)), 
    }; 

    serviceStub.doStuff.and.returnValue(Observable.throw(

     'error!' 
    )); 

serviceStub.doStuff().subscribe(

    (res) => { 

     *working test, can access res* 
    }, 
    (error) => { 

     console.error(error); 
     console.log(error); //Prints 'error!' so throw works. 
     expect(console.error).toHaveBeenCalledWith('error!'); //Is true but won't be accepted for coverage. 
    } 
); 

जैसे कि ये गुमनाम कार्यों के परीक्षण के लिए सबसे अच्छा अभ्यास क्या है? परीक्षण कवरेज सुरक्षित करने के लिए न्यूनतम क्या है?

+1

आपका परीक्षण कोई समझ नहीं आता है; आप उस कॉलबैक को बदल रहे हैं जिसे आप कहते हैं कि आप परीक्षण करना चाहते हैं। जब कोई त्रुटि होती है तो बस 'सब्सक्राइब' का परीक्षण करने पर उसका दूसरा तर्क कॉल होता है, यह आपके कोड का परीक्षण नहीं कर रहा है, यह ढांचे का परीक्षण कर रहा है, जो एक विरोधी पैटर्न है। इसके अलावा आप लगातार लाइनों पर अपने नकली कॉल के लिए दो अलग-अलग परिणाम प्रदान करते हैं। – jonrsharpe

+0

ठीक है, तो इसका परीक्षण करने का एक अच्छा तरीका क्या होगा? एक अलग-अलग ब्लॉक में त्रुटि फेंक रहा है? – user3656550

+1

आपको वास्तविक कार्यान्वयन को कॉल करने की आवश्यकता है, लेकिन आपने यह अनुमान लगाने के लिए पर्याप्त [mcve] नहीं दिखाया है कि यह कैसे प्राप्त किया जा सकता है। – jonrsharpe

उत्तर

7

सुनिश्चित नहीं है कि आप जो कोड दिखा रहे हैं उसका उद्देश्य वास्तव में एक मॉक सेवा का परीक्षण करने का प्रयास कर रहा है। कवरेज समस्या घटक के साथ है और त्रुटि कॉलबैक को कॉल नहीं किया गया है (जिसे केवल त्रुटि होने पर ही बुलाया जाता है)।

मैं आमतौर पर अपनी अधिकांश अवलोकन सेवाओं के लिए जो करता हूं, वह एक नकली बनाना है जिसका विधियां स्वयं ही लौटती हैं। नकली सेवा में subscribe विधि है जो next, error, और complete कॉलबैक स्वीकार करती है। नकली उपयोगकर्ता को त्रुटि जोड़ने के लिए इसे कॉन्फ़िगर करने के लिए कॉन्फ़िगर किया जाता है ताकि error फ़ंक्शन को कॉल किया जा सके, या डेटा जोड़ें, इसलिए next विधि कॉल हो जाती है। इस बारे में मुझे सबसे ज्यादा पसंद यह है कि यह सब तुल्यकालिक है।

नीचे कुछ ऐसा है जो मैं सामान्य रूप से उपयोग करता हूं। यह अन्य मोक्सों के विस्तार के लिए सिर्फ एक अमूर्त वर्ग है। यह मूल कार्यक्षमता प्रदान करता है जो एक अवलोकन योग्य प्रदान करता है। विस्तारित नकली सेवा को केवल विधियों को जोड़ना चाहिए, जो विधि में खुद को लौटाना चाहिए।

import { Subscription } from 'rxjs/Subscription'; 

export abstract class AbstractMockObservableService { 
    protected _subscription: Subscription; 
    protected _fakeContent: any; 
    protected _fakeError: any; 

    set error(err) { 
    this._fakeError = err; 
    } 

    set content(data) { 
    this._fakeContent = data; 
    } 

    get subscription(): Subscription { 
    return this._subscription; 
    } 

    subscribe(next: Function, error?: Function, complete?: Function): Subscription { 
    this._subscription = new Subscription(); 
    spyOn(this._subscription, 'unsubscribe'); 

    if (next && this._fakeContent && !this._fakeError) { 
     next(this._fakeContent); 
    } 
    if (error && this._fakeError) { 
     error(this._fakeError); 
    } 
    if (complete) { 
     complete(); 
    } 
    return this._subscription; 
    } 
} 

अब आप अपने परीक्षण में तुम सिर्फ कुछ की तरह

class MockService extends AbstractMockObservableService { 
    doStuff() { 
    return this; 
    } 
} 

let mockService; 
beforeEach(() => { 
    mockService = new MockService(); 
    TestBed.configureTestingModule({ 
    providers: [{provide: SomeService, useValue: mockService }], 
    declarations: [ TestComponent ] 
    }); 
}); 
it('should call service success',() => { 
    mockService.content = 'some content'; 
    let fixture = TestBed.createComponent(TestComponent); 
    // test component for success case 
}); 
it('should call service error',() => { 
    mockService.error = 'Some error'; 
    let fixture = TestBed.createComponent(TestComponent); 
    // test component for error case 
    // this should handle your coverage problem 
}); 

// this assumes you have unsubscribed from the subscription in your 
// component, which you should always do in the ngOnDestroy of the component 
it('should unsubscribe when component destroyed',() => { 
    let fixture = TestBed.createComponent(TestComponent); 
    fixture.detectChanges(); 
    fixture.destroy(); 
    expect(mockService.subscription.unsubscribe).toHaveBeenCalled(); 
}) 
8

कर आप Observable.throw({status: 404}) और परीक्षण त्रुटि नमूदार के ब्लॉक की तरह बस नकली प्रत्यक्ष फेंक त्रुटि वस्तु कर सकते हैं।

const xService = fixture.debugElement.injector.get(SomeService); 
const mockCall = spyOn(xService, 'method') 
         .and.returnValue(Observable.throw({status: 404})); 
संबंधित मुद्दे