Angular 服务注入其他服务的单元测试
Angular Unit Test for Service injecting other Services
我之前编写过 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 以检查那里的值吗?任何帮助将不胜感激。
您的代码存在几个问题:
- 您的规范文件不会测试您对
HealthViewService
class 的实际实现,因为您提供了某种伪对象 const healthViewService = { createNewPatient: () => {} }
作为服务的实例
- 你期望
healthViewService.createNewPatient
方法存在,这将永远是真的(你没有调用该方法)
- 路由器导航方法需要字符串数组,而不是字符串
以下是您可能会考虑的修复方法(我删除了 HealthService
部分以便为您提供 MWE)
@Injectable()
export class HealthViewService {
constructor(private router: Router) {}
createNewPatient() {
this.router.navigate(["health", "patient"]);
}
}
和相应的规范文件
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 测试,但我不知道如何创建涵盖以下代码的测试。我将包括我已经连接的内容,但测试是基本的。
这是服务文件:
@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 以检查那里的值吗?任何帮助将不胜感激。
您的代码存在几个问题:
- 您的规范文件不会测试您对
HealthViewService
class 的实际实现,因为您提供了某种伪对象const healthViewService = { createNewPatient: () => {} }
作为服务的实例 - 你期望
healthViewService.createNewPatient
方法存在,这将永远是真的(你没有调用该方法) - 路由器导航方法需要字符串数组,而不是字符串
以下是您可能会考虑的修复方法(我删除了 HealthService
部分以便为您提供 MWE)
@Injectable()
export class HealthViewService {
constructor(private router: Router) {}
createNewPatient() {
this.router.navigate(["health", "patient"]);
}
}
和相应的规范文件
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"]);
});
});