繁体   English   中英

Angular 8 karma 测试一个服务而不在构造函数中注入所有服务

[英]Angular 8 karma test a service without injecting all service in the constructor

我是使用 Karma 进行 Angular 测试的新手,我不了解如何正确测试服务。 假设我有必须测试的服务:

    @Injectable()
    export class MyService {
        constructor(private httpService: HttpService) { }

        //methods to test
    }

这是我的测试 class:

    describe('MyService', () => {
      let service: MyService;
      beforeEach(async(() => {
        TestBed.configureTestingModule({
          providers: [MyService],
        }).compileComponents();
        service = TestBed.get(MyService);
      }));
    });

当我运行 ng test 时,它会给出错误NullInjectorError: No provider for HttpService! .
所以我在测试 class 中将 HttpService 添加到 providers 数组中,这样:

    describe('MyService', () => {
      let service: MyService;
      beforeEach(async(() => {
        TestBed.configureTestingModule({
          providers: [MyService, HttpService],
        }).compileComponents();
        service = TestBed.get(MyService);
      }));
    });

HttpService 是这样的:

    @Injectable()
    export class HttpService{
        constructor(private httpService: HttpClient) { }
    }

所以现在我收到错误NullInjectorError: No provider for HttpClient! . (HttpClient 来自@angular/common/http)。
如果我在测试 class 中将 HttpClient 添加到提供程序数组中,那么 HttpClient 构造函数中的所有服务/类都会出现相同的错误,依此类推。 什么是建立服务的正确方法,而不必添加每个提供者,从而导致潜在的无限提供者?

在您的 Testbed 配置中,导入HttpClientTestingModule

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [MyService, HttpService],
    }).compileComponents();
    service = TestBed.get(MyService);
  }));

你也可以考虑

  1. 改变TestBed.get(MyService); TestBed.inject(MyService); 由于不推荐使用TestBed.get(...) TestBed.get 和 new Service(...dependencies) 有什么区别

  2. async更改为waitForAsync因为async已弃用何时在 angular 中使用 waitForAsync

您应该使用HttpClientTestingModule并通过HttpTestingControllerflush方法模拟数据。 这是关于我如何测试服务的Angular 11jasmine 3.6.0的示例。 我希望它可以帮助你:

// Dependencies
import { TestBed, waitForAsync } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

// Assets
import { ExampleService } from './api/example.service';

describe('*[Example Service]: -----------------------------------------', () => {
    let httpTestingController: HttpTestingController;
    let service: ExampleService;

    beforeEach(waitForAsync(() => {
        TestBed.configureTestingModule({
            imports: [
             HttpClientTestingModule
            ]
        }).compileComponents();
        
      httpTestingController = TestBed.inject(HttpTestingController);
      service = TestBed.inject(ExampleService);
    }));
    
    it('1). should get data from GET service', waitForAsync( () => {
      // Arrange
      const expectedData: string[] = ['data1', 'data2'];
      let apiError, apiData;
      // Action
      service.getData().subscribe(response => {
        apiData = response;
      }, error => {
        apiError = error;
      });
      const request = httpTestingController.expectOne(`http://localhost:3000/example`);
      request.flush(expectedData);
      // Assert
      expect(apiData.length).toEqual(2);
      expect(apiError).toBeUndefined();
        }));

});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM