2017-11-25 2 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' }); 
}); 

내가 수동으로 내가 예를 들어 404, 테스트하기 위해 노력하고있어 에러 코드를 설정 테스트의 또 다른 세트를 만들

관련 문제