簡體   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