Angular2服务单元测试报错:TypeError: service.getValue is not a function
解决Angular单元测试中
TypeError: service.getValue is not a function的问题 嘿,这个问题我太熟了!你之所以碰到这个错误,核心原因特别明确——你在测试配置里给MyService提供的模拟对象根本没有getValue()方法。
看你这段测试代码:
{ provide: MyService, useValue: { data: Observable.of(dataStub) } }
你用useValue直接替换了MyService的真实实例,但这个模拟对象只有data属性,完全没定义getValue()方法,所以当你调用service.getValue()的时候,自然会找不到方法报错。
下面给你几种可行的解决方案,根据你的测试需求选就行:
方案1:直接使用真实的MyService类
如果你的服务依赖不算复杂(或者能轻松模拟依赖),可以直接注册真实的服务类:
beforeEach(() => { TestBed.configureTestingModule({ providers: [MyService] // 直接提供服务类,不用模拟对象 }); service = TestBed.inject(MyService); // Angular新版本更推荐用inject代替get });
不过要注意,你的服务构造函数里用到了myOtherObservableReturning这个依赖,所以直接用真实类的话,得先模拟这个依赖:
// 先模拟myOtherObservableReturning的返回值,根据实际类型调整 const mockObservableData = Observable.of({ items: [] }); beforeEach(() => { TestBed.configureTestingModule({ providers: [ MyService, // 替换成你实际的依赖令牌和模拟对象 { provide: MyOtherDependency, useValue: { myOtherObservableReturning: mockObservableData } } ] }); service = TestBed.inject(MyService); });
方案2:正确模拟包含getValue()方法的对象
如果你确实需要模拟MyService而不用真实实例,那模拟对象必须包含测试中用到的所有方法,比如getValue():
beforeEach(() => { // 定义完整的模拟对象,包含需要的属性和方法 const mockMyService = { data: Observable.of(dataStub), getValue: () => 'HelloWorld' // 也可以根据测试需求返回自定义值 }; TestBed.configureTestingModule({ providers: [ { provide: MyService, useValue: mockMyService } ] }); service = TestBed.inject(MyService); });
这样再调用service.getValue()时,就能找到对应的方法了。
方案3:用useClass创建模拟类(适合复杂模拟)
如果模拟逻辑比较多,也可以写一个专门的模拟类:
// 定义模拟服务类,包含需要的属性和方法 class MockMyService { data = Observable.of(dataStub); getValue() { return 'HelloWorld'; } } beforeEach(() => { TestBed.configureTestingModule({ providers: [ { provide: MyService, useClass: MockMyService } ] }); service = TestBed.inject(MyService); });
总的来说,核心就是:不管你用真实服务还是模拟服务,都要确保它包含测试中需要调用的所有方法和属性,别像之前那样漏掉getValue()就行~
内容的提问来源于stack exchange,提问作者Zainu
相关产品推荐
相关产品推荐

