首页 > 解决方案 > 使用服务依赖在 Angular 中进行测试

问题描述

我正在尝试编写我的第一个 Angular 6 测试。我有一个组件,它从服务中返回公司列表。

它看起来像这样:

模板

 <div *ngFor="let company of this.companies">
  <h4 id="company-{{company.id}}>{{company.name}}</h4>
 </div>

组件.ts

import { ApiService } from '../service/api.service';

ngOnInit(): void {
  this.companies = this.apiService.getCompanies();
}

服务

import { COMPANYLIST } from '../companyList';

companyList = COMPANYLIST;

public getCompanies(): Company[] {
  return this.companyList;
}

我想测试我是否可以在组件中看到公司列表。在我的 spec.ts 中,我尝试根据https://angular.io/guide/testing#component-with-a-dependency添加一个模拟的 apiService ,但没​​有成功。

我猜测试应该看起来像这样,但实际上我在将模拟服务注入此测试时遇到了问题。

  it("should show the list of Companies", () => {
    const compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector("company-" + this.company.id).textContent).toContain("Mock Company");
  });

标签: javascriptangularunit-testingkarma-runner

解决方案


该策略是为您的服务注入一个占位符对象。在测试中获取对该占位符对象的引用,然后向其添加假功能,在测试组件时将调用该功能。

示例(我省略了不能说明我要表达的观点的代码

import { ApiService } from '../service/api.service';

describe('CompaniesComponent Tests', () => {

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [CompaniesComponent],
            providers: [
                { provide: ApiService, useValue: {} }
            ]
        }).compileComponents();
        TestBed.compileComponents();
        fixture = TestBed.createComponent(CompaniesComponent);
        comp = fixture.componentInstance;
    });


    it("should show the list of Companies", () => {
      // get service and fake a returned company list 
      const apiService = TestBed.get(ApiService) as ApiService;
      apiService.getCompanies = () => ['Mock Company'];

      // you probably need to call ngOnInit on your component so it retrieves the companies from the api service
      comp.ngOnInit();
      const compiled = fixture.debugElement.nativeElement;
      expect(compiled.querySelector("company-" + this.company.id).textContent).toContain("Mock Company");
    });

推荐阅读