5

में एक त्रुटि प्रतिक्रिया मैं एक interceptor auth-interceptor.service.ts नीचेनकली कैसे कोणीय 4.3 httpclient परीक्षण

import {Injectable, Injector} from '@angular/core'; 
import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http'; 
import {Observable} from 'rxjs/Observable'; 
import {Cookie} from './cookie.service'; 
import {Router} from '@angular/router'; 
import {UserService} from './user.service'; 
import {ToasterService} from '../toaster/toaster.service'; 
import 'rxjs/add/operator/catch'; 
import 'rxjs/add/observable/throw'; 

@Injectable() 
export class AuthInterceptor implements HttpInterceptor { 
    constructor(private injector: Injector) {} 

    private handleError(err: HttpErrorResponse): Observable<any> { 
     let errorMsg; 
     if (err.error instanceof Error) { 
      // A client-side or network error occurred. Handle it accordingly. 
      errorMsg = `An error occurred: ${err.error.message}`; 
     } else { 
      // The backend returned an unsuccessful response code. 
      // The response body may contain clues as to what went wrong, 
      errorMsg = `Backend returned code ${err.status}, body was: ${err.error}`; 
     } 
     if (err.status === 401 || err.status === 403) { 
      this.injector.get(UserService).purgeAuth(); 
      this.injector.get(ToasterService).showError(`Unauthorized`, errorMsg); 
      this.injector.get(Router).navigateByUrl(`/login`); 
     } 
     console.error(errorMsg); 
     return Observable.throw(errorMsg); 
    } 

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { 
     // Clone the request to add the new header. 
     const authReq = req.clone({headers: req.headers.set(Cookie.tokenKey, Cookie.getToken())}); 
     // Pass on the cloned request instead of the original request. 
     return next.handle(authReq).catch(err => this.handleError(err)); 
    } 
} 

अब मैं http.get उपहास करने के लिए त्रुटि फेंक, ताकि विधि handleError त्रुटि संदेश सांत्वना कोशिश कर रहा हूँ।

नीचे परीक्षण का मामला करने के लिए अपने दृष्टिकोण है auth-interceptor.service.specs.ts

import {async, inject, TestBed} from '@angular/core/testing'; 

import {AuthInterceptor} from './auth-interceptor.service'; 
import {ApiService} from './api.service'; 
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; 
import {environment} from '../../../environments/environment'; 

describe(`AuthInterceptor`,() => { 
    const somePath = `/somePath`; 

    beforeEach(() => { 
     TestBed.configureTestingModule({ 
      imports: [HttpClientTestingModule], 
      providers: [AuthInterceptor, ApiService] 
     }); 
    }); 

    it(`should be created`, inject([AuthInterceptor], (service: AuthInterceptor) => { 
     expect(service).toBeTruthy(); 
    })); 


    it(`should log an error to the console on error on get()`, async(inject([ApiService, HttpTestingController], 
     (apiService: ApiService, httpMock: HttpTestingController) => { 
      spyOn(console, 'error'); 
      apiService.get(somePath).subscribe((res) => { 
       console.log(`in success:`, res); 
      }, (error) => { 
       console.log(`in error:`, error); 
      }); 

      const req = httpMock.expectOne(`${environment.apiUri}${somePath}`); 
      req.flush({ 
       type: 'ERROR', 
       status: 404, 
       body: JSON.stringify({color: `blue`}) 
      }); 
      expect(console.error).toHaveBeenCalled(); 
     })) 
    ); 
}); 

जब प्रतिक्रिया निस्तब्धता, मुझे यकीन है कि कैसे एक त्रुटि प्रतिसाद फ्लश करने के लिए, ताकि विधि handleError मेरी इंटरसेप्टर और उस में अंत में कहा जाएगा नहीं कर रहा हूँ कॉल console.error। दस्तावेज़ीकरण में मेरी स्थिति का कोई उदाहरण नहीं है। किसी भी मदद या सुझाव की सराहना की है।

+1

आपकी 'req' वस्तु 'testRequest' कक्षा का एक उदाहरण है। इसमें 'त्रुटि()' विधि भी है। क्या आपने 'req.error' (नया त्रुटि इवेंट ('असफल'), {status: 404}) की तरह कुछ करने की कोशिश की; '? –

उत्तर

6

expectOneHttpTestingController कक्षा में विधि TestRequest ऑब्जेक्ट देता है। इस टेस्टआरक्वेट क्लास में flush विधि है जिसका उपयोग

दोनों सफल और असफल प्रतिक्रिया देने के लिए किया जा सकता है।

हम कुछ अतिरिक्त प्रतिक्रिया शीर्षकों (यदि कोई हो) के साथ शरीर को लौटकर अनुरोध को हल कर सकते हैं। प्रासंगिक जानकारी here मिल सकती है।

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

http = TestBed.get(HttpTestingController); 
let response:any; 
let errResponse: any; 
const mockErrorResponse = { 
    status: 404, statusText: 'Bad Request' 
}; 
const data = 'Invalid request parameters'; 
apiService.get(somePath).subscribe(res => response=res, err => errResponse=err); 
http.expectOne('url/being/monitored').flush(data, mockErrorResponse); 
expect(errResponse).toBe(data); 

नोट: इस टिप्पणी लिखने के समय, statusTextmockErrorResponse में आवश्यक है। संबंधित जानकारी here मिल सकती है।

पीएस: TestRequest वर्ग की विधि हमारे परीक्षण मामले में नेटवर्क त्रुटि अनुकरण करने के लिए उपयोग की जा सकती है, क्योंकि यह त्रुटि के उदाहरण की अपेक्षा करता है। निम्नलिखित कोड स्निपेट दिखाता है कि।

http.expectOne(someUrl).error(new ErrorEvent('network error')); 
संबंधित मुद्दे