如何用Jasmine为Angular 2+中构造函数含调用的服务编写单元测试
如何用Jasmine为Angular服务的构造函数分支编写单元测试?
我来帮你搞定这个单元测试的问题!你的Somename服务在构造函数里会根据window.cordova是否存在,调用不同的私有方法,用Jasmine来覆盖这两个分支的核心思路就是模拟window对象的cordova属性,然后验证对应私有方法是否被正确触发。
下面是具体的实现步骤和代码示例:
第一步:搭建测试基础框架
首先导入Angular测试所需的模块,创建测试套件,并且在每次测试前重置window对象,避免测试用例之间互相干扰:
import { TestBed } from '@angular/core/testing'; import { Somename } from './somename.service'; declare var window: any; describe('Somename Service', () => { let service: Somename; beforeEach(() => { TestBed.configureTestingModule({ providers: [Somename] }); // 每次测试前清空window.cordova,保证测试环境干净 delete window.cordova; });
第二步:测试window.cordova存在的分支
我们先模拟window.cordova存在的场景,然后验证私有方法function1是否被调用:
it('should call private function1 when window.cordova is present', () => { // 模拟window.cordova存在 window.cordova = {}; // 对私有方法创建spy(因为是私有方法,需要用as any绕过TypeScript类型检查) const function1Spy = spyOn(Somename.prototype as any, 'function1'); // 实例化服务,此时构造函数会执行 service = TestBed.inject(Somename); // 验证function1被调用了一次 expect(function1Spy).toHaveBeenCalled(); });
第三步:测试window.cordova不存在的分支
接下来测试另一个分支,验证当window.cordova不存在时,function2会被调用:
it('should call private function2 when window.cordova is not present', () => { // 此时window.cordova已经在beforeEach中被删除,无需额外设置 const function2Spy = spyOn(Somename.prototype as any, 'function2'); service = TestBed.inject(Somename); expect(function2Spy).toHaveBeenCalled(); }); });
关键注意点
- 重置window对象:一定要在每个测试前重置
window.cordova,否则前一个测试的修改会影响后续测试的结果。 - 提前创建spy:必须在实例化服务之前创建私有方法的spy,因为构造函数会在实例化时立即执行,晚了就捕获不到调用了。
- 私有方法的spy处理:由于TypeScript不允许直接访问私有成员,所以用
as any来绕过类型检查,这在单元测试中是合理的做法——我们的目标是验证逻辑分支,而不是纠结于私有成员的访问限制。
内容的提问来源于stack exchange,提问作者Chetan Khilare
相关产品推荐
相关产品推荐

