'How jasmine spyOn a generic method

I try to make a spy on a generic method in typescript,
but cannot get Jasmine to recognise it.


I have code

http: HttpClient <- Not proper code, just showing type.
...
this.http.get<Customer[]>(url);

where I want to mock the get<...> method.

const httpMock = {} as HttpClient;
spyOn(httpMock, 'get')
   .and.returnValue(of({} as Customer[]));

But when I run the test I get

Error: : get() method does not exist
Usage: spyOn(, )



Solution 1:[1]

The remedy was to not use any generics when mocking.

describe('UserService', () => {
  it('should return proper users', (done) => {

    const returnedUsers = [...];

    const mock = {
      get: (_) => of({returnUsers}),
    } as HttpClient;

    const sut = new UserService(mock);

    //  Act.
    sut.getUser()
        .subsribe(users => {

            //  Assert.
            ...

            done();
        });
  });
});

Solution 2:[2]

First of all, I am aware of HttpClientTestingModule, but in simple cases it can be an overkill. If you properly mock HttpClient, for example, with MockBuilder, like this:

beforeEach(() => {
  return MockBuilder()
    .keep(YourService)
    .mock(HttpClient);
});

Then your code will work.

spyOn(http, 'get').and.returnValue(of([] as Customer[]));

Notice you need [] instead of {}. However, it is usually a good idea to have a request object instead, which will have an array of items/row + other metadata. This is how most real-world API responses will come back.

If your app doesn't need any metadata, you can map to an array via pipe. But then it's flexible enough to change at any point.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 LosManos
Solution 2 Victor Zakharov