【问题标题】:Angular Unit Test for Service injecting other Services用于注入其他服务的服务的 Angular 单元测试
【发布时间】:2021-03-26 21:22:00
【问题描述】:

我以前写过 Angular 测试,但我不知道如何创建一个涵盖以下代码的测试。我将包括我连接的内容,但测试是基本的。

这里是服务文件:

@Injectable()
export class HealthViewService {
    constructor(private readonly healthService: HealthService, private router: Router){}

    createNewPatient() {
       this.healthService.currentStatus = this.healthService.getInitialStatus();
       this.router.navigate('health/patient');
    }
}

这是规范文件:

import {HealthViewService} from '<not showing pathway>';
import {HealthService} from '<not showing pathway again>';

const healthViewService = {
    createNewPatient: () => {}
}

const healthServiceStub = { currentStatus: () { return StatusTarget.Inbound; }}

let routerStub = { navigate: () => {} }

describe('HealthViewService', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [{provide: Router, useValue: routerStub }, 
                       {provide: HealthService, useValue: healthServiceStub },
                       {provide: HealthViewService, useValue: healthViewService}]
        })
    });

    describe('createNewPatient', () => {
       it('it should route to patient page', () => {
           expect(healthViewService.createNewPatient).toBeTruthy();
       });
    });
});

好消息是这个测试通过了,但它并不是一个很好的代码覆盖测试。我的问题是:有什么方法可以正确地模拟路由器并观察路由器导航的位置吗?我可以监视 HealthService 以检查那里的值吗?任何帮助将不胜感激。

【问题讨论】:

标签: angular unit-testing angular8


【解决方案1】:

代码中的几个问题:

  • 您的规范文件不会测试您对 HealthViewService 类的实际实现,因为您提供了某种假对象 const healthViewService = { createNewPatient: () =&gt; {} } 作为服务实例
  • 您希望healthViewService.createNewPatient 方法存在,这将始终为真(您不调用该方法)
  • 路由器导航方法需要一个字符串数组,而不是字符串

以下是您可能会考虑的修复(我删除了 HealthService 部分给您一个 MWE)

@Injectable()
export class HealthViewService {
  constructor(private router: Router) {}

  createNewPatient() {
    this.router.navigate(["health", "patient"]);
  }
}

以及对应的spec文件

import { TestBed } from "@angular/core/testing";
import { Router } from "@angular/router";
import { HealthViewService } from "./health-view-service.service";

describe("HealthViewServiceService", () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        // provide the actual implementation you want to test
        // shortcut for {provide: HealthViewService, useClass: HealthViewService}
        HealthViewService,
        // provide a mocked Router, injected through inversion of control mechanism offered by angular
        { provide: Router, useValue: { navigate: () => {} } },
      ],
    });
  });

  it("createNewPatient() should navigate to health/patient", () => {
    const service = TestBed.inject(HealthViewService);
    const router = TestBed.inject(Router);
    const spy = spyOn(router, "navigate");

    service.createNewPatient();

    expect(spy).toHaveBeenCalledWith(["health", "patient"]);
  });
});

【讨论】:

  • 注意:这是针对 Angular 11。对于 Angular 8,您可能需要将 TestBed.inject 替换为 TestBed.get
  • 这正是我要找的!谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-05-29
  • 2013-10-17
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 1970-01-01
  • 2020-11-20
相关资源
最近更新 更多