I'm following this example to make a unit test for service (get request coming from spring app backend) https://angular.io/guide/testing#testing-http-services
Service class :
@Injectable()
export class TarifService {
  constructor(private messageService: MessageService, private http: HttpClient) { }
  public getTarifs(): Observable<Tarif[]> {
    return this.http.get<Tarif[]>(tarifffsURL).pipe(
      tap(() => {}),
      catchError(this.handleError('getTarifs', []))
    );
  }
}
Unit Test
describe('TarifService', () => {
  let tarifService: TarifService;
  let httpClientSpy: { get: jasmine.Spy };
  let expectedTarifs;
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ToastrModule.forRoot(), HttpClientModule, HttpClientTestingModule],
      providers: [TarifService, HttpClient, MessageService]
    });
    httpClientSpy = jasmine.createSpyObj('HttpClient', ['get']);
    tarifService = new TarifService(<any> MessageService,<any> httpClientSpy);
  });
  it('should be created', inject([TarifService], (service: TarifService) => {
    expect(service).toBeTruthy();
  }));
  it('should return expected tarif (HttpClient called once)', () => {
    const expectedTarifs: Tarif[] =
      [{ id: 1, name: 'Tarif1', value: '20' }, { id: 2, name: 'Tarif2', value:'30' }];
    httpClientSpy.get.and.returnValue(expectedTarifs);
    tarifService.getTarifs().subscribe(
      tarifs => expect(tarifs).toEqual(expectedTarifs, 'expected tarifs'),
      fail
    );
    expect(httpClientSpy.get.calls.count()).toBe(1, 'one call');
  });
});
When running the tests, I keep having this error
TarifService should return expected tarif (HttpClient called once)
TypeError: this.http.get(...).pipe is not a function
what could be the cause of this?
The problem is that when your spy is being called, it is returning an Array, and Array does not have a pipe function. You need to return an Observable from your spy, something like this
const expectedTarifs: Tarif[] =
  [{ id: 1, name: 'Tarif1', value: '20' }, { id: 2, name: 'Tarif2', value:'30' }];
httpClientSpy.get.and.returnValue(Observable.of(expectedTarifs));
See how the returnValue is Observable.of(expectedTarifs). Observable.of creates an Observable that emits some values you specify as arguments, immediately one after the other, and then emits a complete notification. See the docs
In the latest versions of rxjs we can use the of operator
import { of } from 'rxjs';
//... omitting some code here for brevity 
const expectedTarifs: Tarif[] =
  [{ id: 1, name: 'Tarif1', value: '20' }, { id: 2, name: 'Tarif2', value:'30' }];
httpClientSpy.get.and.returnValue(of(expectedTarifs));
Hope it helps
I had to do this to get mine to work:
import { from } from 'rxjs';
then:
return from([expectedTarifs]);
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With