【问题标题】:Angular testing Service with params return an mocked observable带有参数的角度测试服务返回一个模拟的 observable
【发布时间】:2020-12-15 13:38:55
【问题描述】:

我对所有不同类型的单元测试仍然很陌生,我又一次陷入了对服务的测试。

这是我要测试的服务中的功能:

For your information:
this.setParams returns an object like {name: 'Test', id: 3}


  getDataCount(dataparams: Filter): Observable<number> {
    const url = 'http://blablabla.com';
    const params = this.setParams(dataparams);
    return new Observable<number>(observer => {
      this.httpc.get<number>(url, { params }).subscribe(
        (data) => {
          observer.next(data);
          observer.complete();
        }
      );
    }
    );
  }

我的测试设置是:

describe('MyDataService', () => {
  let service: DataService;
  let mockParams: Filter;
  let mockCount: number;

  mockParams = { name: 'Test', id: 3 };
  mockCount = 358;

  beforeEach(() => {

    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule
        ]
    });
    service = TestBed.inject(DataService);
  });

我的测试是这样的:

  it('should return mockCount', async () => {
    const test = await service.getOperatingDataCount(mockParams).toPromise();
    expect(test).toBe(mockCount);
  });

但它返回“异步函数未在 5000 毫秒内完成(由 jasmine.DEFAULT_TIMEOUT_INTERVAL 设置)”。我也阅读了其他线程,但我仍然无法弄清楚如何为此编写适当的测试。谁能指出我正确的方向?

【问题讨论】:

    标签: angular typescript unit-testing rxjs jasmine


    【解决方案1】:

    你应该在调用req.flush() 之后await 承诺。它将以模拟数据响应,导致 this.httpc.get() Observable 解析。

    只有当你的 observable 发出一个值时,你的 Promise 才能被解决或拒绝。 因此,在调用req.flush()之前,promise 无法解析并被拒绝,从而导致超时错误。

    这是一个使用"@angular/core": "~11.0.3"的工作示例

    data.service.ts:

    import { HttpClient } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    import { Observable } from 'rxjs';
    
    export type Filter = any;
    
    @Injectable()
    export class DataService {
      constructor(private httpc: HttpClient) {}
      setParams(dataparams: Filter) {
        return dataparams;
      }
      getDataCount(dataparams: Filter): Observable<number> {
        const url = 'http://blablabla.com';
        const params = this.setParams(dataparams);
        return new Observable<number>((observer) => {
          this.httpc
            .get<number>(url, { params })
            .subscribe((data) => {
              console.log(data);
              observer.next(data);
              observer.complete();
            });
        });
      }
    }
    

    data.service.spec.ts:

    import { TestBed } from '@angular/core/testing';
    import { DataService, Filter } from './data.service';
    import {
      HttpClientTestingModule,
      HttpTestingController,
    } from '@angular/common/http/testing';
    
    fdescribe('MyDataService', () => {
      let dataService: DataService;
      let mockParams: Filter;
      let mockCount: number;
      let httpTestingController: HttpTestingController;
    
      beforeEach(() => {
        TestBed.configureTestingModule({
          imports: [HttpClientTestingModule],
          providers: [DataService],
        });
        dataService = TestBed.inject(DataService);
        httpTestingController = TestBed.inject(HttpTestingController);
      });
    
      it('should get data', async () => {
        mockParams = { name: 'Test', id: 3 };
        mockCount = 358;
    
        const promise = dataService.getDataCount(mockParams).toPromise();
        const req = httpTestingController.expectOne(
          'http://blablabla.com?name=Test&id=3'
        );
        expect(req.request.method).toEqual('GET');
        req.flush(mockCount);
        const actual = await promise;
        expect(actual).toBe(358);
        httpTestingController.verify();
      });
    });
    

    单元测试结果:

    【讨论】:

      猜你喜欢
      • 2020-10-26
      • 2020-06-24
      • 2018-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多