如何使用Jasmine的spyOn函数来对一个通用方法进行监视

4

我试图在TypeScript中监视一个通用方法,但无法使Jasmine识别它。


我的代码如下:

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

我想模拟get<...>方法。

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

但是当我运行测试时,会出现以下错误:

错误:get()方法不存在
用法:spyOn(,)


尝试使用const httpMock = { get: () => null } as HttpClient;,但是在测试HTTP时应该使用HttpTestingController(https://angular.io/api/common/http/testing/HttpTestingController)。 - AliF50
HttpTestingController难道不能解决确保调用已经被执行的问题吗?它不是模拟返回结果的吗? - LosManos
1
你也可以使用flush方法模拟响应。https://medium.com/better-programming/testing-http-requests-in-angular-with-httpclienttestingmodule-3880ceac74cf 看看吧。 - AliF50
2个回答

1
解决方法是在模拟时不要使用任何通用类。
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();
        });
  });
});

这是一些丑陋的代码。你需要10倍的代码来测试一个简单的方法。如果这个方法不简单呢? - Victor Zakharov

0
首先,我知道HttpClientTestingModule,但在简单的情况下,它可能会过度杀伤力。如果您使用MockBuilder正确地模拟HttpClient,例如像这样:
beforeEach(() => {
  return MockBuilder()
    .keep(YourService)
    .mock(HttpClient);
});

那么你的代码就可以正常工作了。

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

注意需要使用[]而不是{}。然而,通常最好使用请求对象,该对象将具有项目/行数组和其他元数据。这是大多数真实世界的API响应返回的方式。

如果您的应用程序不需要任何元数据,则可以通过管道映射到数组。但是,它足够灵活,可以在任何时候更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接