问题描述
我有一个有关使用Jasmin / Karma进行Angular单元测试的查询。
我有以下3种服务:EmployeeService,SalaryService和TaxationService。
EmployeeService依赖于注入到其构造函数中的SalaryService。
SalaryService依赖于Taxation服务,该服务又被注入其构造函数中。
在我的employee.component.spec.ts中,我有以下代码:
let employeeService: EmployeeService;
let salaryServiceSpy: jasmine.SpyObj<SalaryService>;
Testbed.configureTestingModule({
providers: [EmployeeService],declarations: [ EmployeeComponent ]
})
.compileComponents();
employeeService = Testbed.inject(EmployeeService);
salaryServiceSpy = Testbed.inject(SalaryService) as jasmine.SpyObj<SalaryService>;
}));
it('should return Name and Salary',() => {
expect(employeeService.getEmployeeNameAndSalary(1)).toBe("John Smith receives: $12345 and tax value of 15%");
});
代码可以正常工作,我的问题是为什么我们需要使用Jasmine Spy-代码也可以在没有间谍服务的情况下正常工作?
salaryServiceSpy = Testbed.inject(SalaryService) as jasmine.SpyObj<SalaryService>;
我已将以下内容用作参考:https://angular.io/guide/testing-services。
如果下面的示例更加清楚,则需要创建ValueServiceSpy吗?是不是Testbed.inject还没有注入所有依赖项和“其他依赖项的依赖项”?
解决方法
让我解释一下,几年前我也有类似的问题:
为什么在角度单元测试中应使用Jasmine Spy Object?
答案:因为创建spy
时,您可以执行单元测试中的以下任务:
-
您可以检查函数是否已被调用(使用`expect(component.method).toHaveBeenCalled())
-
您甚至可以覆盖实际的实现方式(写在
service.ts
中),并返回一些虚拟数据来为单元测试用例创建多个方案。
您检查这个article的地方,因为我在其中使用了存根,这与您在角度指南中看到的不同。我之所以使用Stubs
是因为我可以通过简单地使用other-component.spec.ts
注入providers
来重用其他使用相同服务的useClass
。花些时间,看看我如何使用.toHaveBeenCalled()
[来理解我的 point 1 ],以及如何使用.returnValue()来重新创建error
服务行为。
创建ValueServiceSpy有什么需要? TestBed.inject是否尚未注入所有依赖项和“其他依赖项的依赖项”?
答案:是的,TestBed.inject
确实注入了依赖项,但是注入了实际的ValueService
。对于单元测试,您想隔离要测试的服务“(在这种情况下,您要测试MasterService
而不是ValueService
)。
因此,在测试mock
时 ValueService
MasterService
很有意义。
这有意义吗?