angularjasmine

Testing service returning error from http.get


I have this service:

@Injectable({providedIn: 'root'})
export class CaseManagementService {

    constructor(private http: HttpService) {
    }

    getDocumentDetails(caseId: string, docId: string): Observable<DocumentDetails> {
        return this.http.get<DocumentDetails>(UrlConstants.CASES_URL + `/${caseId}/Documents/${docId}/Details`);
    }
}

and for testing purposes I have created the following jasmine test:

it('should handle error when retrieving document details', () => {
    const errorResponse = new HttpErrorResponse({ error: 'error', status: 500 });
    spyOn(service['http'], 'get').and.returnValue(of(errorResponse));

    service.getDocumentDetails('case1', 'doc1').subscribe({
        next: () => fail('expected an error, not document details'),
        error: error => expect(error.message).toContain('error')
    });

    expect(service['http'].get).toHaveBeenCalledWith(UrlConstants.CASES_URL + '/case1/Documents/doc1/Details');
});

No matter what I do I keep ending in the next section of my subscribe and it would be much appreciated if anyone can explain to me what I'm doing wrong.


Solution

  • You should use throwError instead of of.

    import { throwError } from 'rxjs';
    
    it('should handle error when retrieving document details', () => {
        const errorResponse = new HttpErrorResponse({ error: 'error', status: 500 });
        spyOn(service['http'], 'get').and.returnValue(throwError(() => errorResponse));
    
        service.getDocumentDetails('case1', 'doc1').subscribe({
            next: () => fail('expected an error, not document details'),
            error: error => expect(error.message).toContain('error')
        });
    
        expect(service['http'].get).toHaveBeenCalledWith(UrlConstants.CASES_URL + '/case1/Documents/doc1/Details');
    });
    

    HttpErrorResponse is not throwing an error itself and of creates a successful observable that emits a value.