You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 09:15:32