Anna
Anna

Reputation: 59

Unit test for service with Jasmine does not return data

guys! I'm new in testing person and stuck with this issue. I'm trying to write the unit test for my service, which getting data from the server. Classical case:

import {TestBed} from '@angular/core/testing';
import {ShiftsService} from "./shifts.service";
import {Shift} from "../shift/shift";

describe('ShiftService - testing HTTP request method getShifts()', () => {
  let httpTestingController: HttpTestingController;

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

  it('can test HttpClient.get', () => {
    let shifts = new Array<Shift>();
    let shiftsService;
    let calendarMonth = new Date().getMonth()+2;
    let calendarYear  = new Date().getFullYear();
    shiftsService = TestBed.inject(ShiftsService);
    httpTestingController = TestBed.inject(HttpTestingController);
    shiftsService.getShifts(calendarYear, calendarMonth).subscribe(response => {expect(response).toBe(response.length);
    console.log(response);
    });

    let apiRequest:string = '/api/shifts?year='.concat(calendarYear.toString()).concat('&month=').concat(calendarMonth.toString());
    const req = httpTestingController.expectOne(apiRequest);
    console.log(apiRequest);
    expect(req.request.method).toBe('GET');

    req.flush(shifts);
  });

  afterEach(() => httpTestingController.verify());
});

My method inside service file looks like this:

getShifts (year: number, month: number): Observable<Shift[]> {
    let params = new HttpParams();
    params = params.append('year', year.toString());
    params = params.append('month', month.toString());

    return this.http.get<Shift[]>(this.shiftsUrl, { params: params })
      .pipe(tap((shifts) => shifts),
        catchError((err) => this.handleError(err)))
  }

I got the error: Error: Expected [ ] to be 0. When I print out the response variable I got that it is empty! But I'm sure that this method works fine! It works fine in my app! Could you please help me to fix this issue ? How to correct my testing method to test the service ?

Upvotes: 1

Views: 1172

Answers (1)

AliF50
AliF50

Reputation: 18889

At the very end, you are doing req.flush(shifts) and shifts = new Array<Shift>(); which is essentially []. The flush is what you want the HTTP get request to respond with, in this instance it is an empty array.

In the subscribe, you are asserting response ([]) to equal response.length which is 0.

Try this:

it('can test HttpClient.get', (done) => { // add done callback to be able to call it in the subscribe
    let shifts = new Array<Shift>();
    let shiftsService;
    let calendarMonth = new Date().getMonth()+2;
    let calendarYear  = new Date().getFullYear();
    shiftsService = TestBed.inject(ShiftsService);
    httpTestingController = TestBed.inject(HttpTestingController);
    shiftsService.getShifts(calendarYear, calendarMonth).subscribe(response => {
       // we have to use toEqual because toBe does a deep assertion
       // but the array to compare to is in a different location in memory so 
       // toBe would fail
       expect(response).toEqual([]);
       console.log(response);
       // call done to tell the unit test you are done with this test
       done();
    });

    let apiRequest:string = '/api/shifts?year='.concat(calendarYear.toString()).concat('&month=').concat(calendarMonth.toString());
    const req = httpTestingController.expectOne(apiRequest);
    console.log(apiRequest);
    expect(req.request.method).toBe('GET');

    shifts.push(/* push a shift here */) // change the shifts array to what you want the server to respond with 
    req.flush(shifts);
  });

Upvotes: 2

Related Questions