如何用Jasmine在Component spec.ts中Mock服务变量screenName并解决undefined问题
解决Angular测试中Mock服务属性不生效的问题
你的问题出在两个核心点:
jasmine.createSpyObj的第二个参数是方法名称数组,但screenName是服务的属性而非方法,这么写会把它处理成Spy方法,导致赋值无效。- 你创建的Mock服务实例没有正确关联到组件依赖的
sampleService,组件实际使用的还是未Mock的原始实例。
下面给你两种可行的解决方式:
方式一:用SpyObj的属性参数定义Mock属性
Jasmine的createSpyObj支持第三个参数传入属性对象,直接定义需要Mock的服务属性:
// 在测试的beforeEach块中配置TestBed beforeEach(() => { // 创建带初始属性的Mock服务 const mockSampleService = jasmine.createSpyObj('SampleService', [], { screenName: '' }); TestBed.configureTestingModule({ declarations: [SampleComponent], providers: [ { provide: SampleService, useValue: mockSampleService } ] }); // 获取组件和Mock服务的实例 component = TestBed.inject(SampleComponent); sampleService = TestBed.inject(SampleService); }); it('sample Screen as Create', () => { // 动态设置属性值 sampleService.screenName = 'CREATE'; component.setScreen(); // 替换为实际业务逻辑的断言,比如检查分支执行后的组件状态 // expect(component.someTargetProperty).toBe(...); });
方式二:直接创建模拟对象(适合无方法的简单服务)
如果你的SampleService只有属性、没有需要Mock的方法,直接创建普通对象更简单:
beforeEach(() => { const mockSampleService = { screenName: '' }; TestBed.configureTestingModule({ declarations: [SampleComponent], providers: [ { provide: SampleService, useValue: mockSampleService } ] }); component = TestBed.inject(SampleComponent); sampleService = TestBed.inject(SampleService); }); it('sample Screen as Create', () => { sampleService.screenName = 'CREATE'; component.setScreen(); // 添加对应业务断言 });
额外注意
- 必须通过
TestBed.inject获取组件和服务实例,确保组件依赖的是你配置的Mock服务。 - 原测试中的
expect(component.setScreen).toBeTruthy();没有实际意义,应该断言setScreen执行后组件的状态变化(比如某个变量值、DOM元素状态等)。
内容的提问来源于stack exchange,提问作者Ashwini
相关产品推荐
相关产品推荐

