简体   繁体   English

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

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

I'm new to Angular testing with Karma and I'm not understanding how to properly test a service.我是使用 Karma 进行 Angular 测试的新手,我不了解如何正确测试服务。 Let's say I have this service that I have to test:假设我有必须测试的服务:

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

        //methods to test
    }

and this is my test class:这是我的测试 class:

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

When I run ng test it gives the error NullInjectorError: No provider for HttpService!当我运行 ng test 时,它会给出错误NullInjectorError: No provider for HttpService! . .
So I add HttpService into providers array in test class, this way:所以我在测试 class 中将 HttpService 添加到 providers 数组中,这样:

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

HttpService is this: HttpService 是这样的:

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

So now I get the error NullInjectorError: No provider for HttpClient!所以现在我收到错误NullInjectorError: No provider for HttpClient! . . (HttpClient is from @angular/common/http). (HttpClient 来自@angular/common/http)。
If I add HttpClient to providers array in test class then I get the same error for all the services/class inside HttpClient constructor, and so on.如果我在测试 class 中将 HttpClient 添加到提供程序数组中,那么 HttpClient 构造函数中的所有服务/类都会出现相同的错误,依此类推。 What is the correct way to instatiate a service, without having to add each providers, leading to potential infinite providers?什么是建立服务的正确方法,而不必添加每个提供者,从而导致潜在的无限提供者?

In your Testbed configuration, import HttpClientTestingModule在您的 Testbed 配置中,导入HttpClientTestingModule

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

You may consider also你也可以考虑

  1. changing TestBed.get(MyService);改变TestBed.get(MyService); to TestBed.inject(MyService);TestBed.inject(MyService); as TestBed.get(...) is deprecated What's the difference between TestBed.get and new Service(...dependencies)由于不推荐使用TestBed.get(...) TestBed.get 和 new Service(...dependencies) 有什么区别

  2. changing async to waitForAsync as async is deprecated When to use waitForAsync in angularasync更改为waitForAsync因为async已弃用何时在 angular 中使用 waitForAsync

you should use HttpClientTestingModule and mock data with HttpTestingController and the flush method.您应该使用HttpClientTestingModule并通过HttpTestingControllerflush方法模拟数据。 this is an example with Angular 11 and jasmine 3.6.0 about how I test services.这是关于我如何测试服务的Angular 11jasmine 3.6.0的示例。 I hope it helps you:我希望它可以帮助你:

// 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