2017-11-25 29 views
1

私は、http呼び出しを行う責任があるサービスを単体テストしようとしています。私は成功のリクエストをテストすることができましたが、レスポンスのステータスコードが200と異なる場合にテストを行うことができません。角度単位テストがHttpClient要求に失敗しました

たとえば、リクエストが404ステータスを返すとします正しくテストすることはできません。

これは私のサービスです。

@Injectable() 
export class ApiService { 
    constructor(
     private _http: HttpClient, 
     private _router: Router, 
     private _toast: ToastsManager, 
     private _auth: AuthService, 
    ) { } 

    public apiGet(url: string) { 
     return this._http 
      .get(url) 
      .catch(this.handleError.bind(this)); 
    } 

    private handleError(error) { 
     if (error.status === 401) { 
      this._auth.logout(); 
      return Observable.throw(error); 
     } 

     if (error.status === 404) { 
      this._router.navigateByUrl('not-found'); 
      return Observable.throw(error); 
     } 

     if (error.error && error.error.message) { 
      this._toast.error(error.error.message); 
     } else { 
      this._toast.error('Something went wrong'); 
     } 

     return Observable.throw(error); 
    } 
} 

そして、これは私がテストだ方法です:

describe('ApiService',() => { 
    let service: ApiService; 
    let backend: HttpTestingController; 

    const mockSuccessResponse = { value: '123', name: 'John' }; 
    const mockSuccessStatus = { status: 200, statusText: 'Ok' }; 

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

     service = TestBed.get(ApiService); 
     backend = TestBed.get(HttpTestingController); 
    }); 

    it('should call the apiGet() function with success',() => { 
     service.apiGet('mock/get/url').subscribe(response => { 
      expect(response).toEqual(mockSuccessResponse); 
     }); 

     const req = backend.expectOne('mock/get/url'); 

     expect(req.request.url).toBe('mock/get/url'); 
     expect(req.request.method).toBe('GET'); 

     req.flush(mockSuccessResponse, mockSuccessStatus); 
    }); 

    it('should execute handleError function on status different of 200',() => { 
     service.apiGet('mock/error/url').subscribe(response => { }, error => { 
      // Handle the error cases here (?) 
     }); 

     const req = backend.expectOne('mock/error/url'); 

     req.flush(null, { status: 404, statusText: 'Not Found' }); 
    }); 

    afterEach(() => { 
     backend.verify(); 
    }); 
}); 

私はここから継続するのか分かりません。 expect(service.handleError()).toHaveBeenCalled();のようなことをしようとすると、handleError is a private methodのようなエラーが出ます。

また、authServiceの機能logout()が呼び出されるか、404エラーでnot-foundにルートが変更されるかどうかをテストする必要があります。

レスポンスのステータスが200と異なるこれらのケースをテストできるようにするにはどうすればよいですか?

答えて

0

この問題を解決する方法は、handleError関数が呼び出されたかどうかをテストし、handleError関数だけをテストする別のテストセットを作成することでした。

it('should navigate to route "not-found" on status 404',() => { 
    spyOn(router, 'navigateByUrl'); 

    const mockError = { 
     status: 404, 
     error: { 
      message: 'Page not found', 
     }, 
    }; 

    service['handleError'](mockError); 

    // Here we adapt to test whatever condition it is 
    // Mine is a simple redirect to an error page 
    expect(router.navigateByUrl).toHaveBeenCalledWith('not-found'); 
}); 
:そして

it('should execute handleError function on status different of 200',() => { 
    // "as any" to avoid the "private method" type errors 
    spyOn(service as any, 'handleError'); 

    service.apiGet('mock/get/url').subscribe(() => { }, error => { 
     // This is where I just check if the function was called 
     // It also needs to be service['handleError'] to avoid type errors on private method 
     expect(service['handleError']).toHaveBeenCalled(); 
    }); 

    const req = backend.expectOne('mock/get/url'); 

    req.flush(null, { status: 400, statusText: 'Error' }); 
}); 

私は手動でIは、例えば404、テストしようとしているエラーコードを設定試験の別のセットを作成します

関連する問題