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

使用ng-mocks时如何在特定测试中修改mock provider的取值?

问题核心原因

  1. 你自行定义了固定的mockActivatedRoute字面量对象并通过useValue注入,MockInstance仅对ng-mocks托管的mock实例生效,对自定义的字面量对象不会生效。
  2. 你在最外层的beforeEach中已经执行了MockRender完成组件初始化,嵌套describe中对provider的修改执行在组件初始化之后,自然不会更新已经生成的routeId。

可用解决方案

方案1:使用ng-mocks托管mock(推荐)

让ng-mocks接管ActivatedRoute的mock生成,配合MockInstance动态修改属性,同时将组件渲染逻辑后置到provider修改完成后执行:

describe('MyComponent', () => {
  MockInstance.scope('all');

  beforeEach(() => {
    // 让ng-mocks生成mock实例,默认配置id为1
    return MockBuilder(MyComponent, MyModule)
      .mock(ActivatedRoute, {
        snapshot: { params: { id: 1 } }
      });
  });

  // 抽离公共渲染方法,在provider配置完成后调用
  function renderComponent() {
    fixture = MockRender(MyComponent);
    component = fixture.point.componentInstance;
  }

  it('should have an id of 1', () => {
    renderComponent();
    expect(component.routeId).toEqual(1);
  });

  describe('when it inits with a different id', () => {
    // 在渲染前修改ng-mocks托管的ActivatedRoute属性
    beforeEach(() => MockInstance(ActivatedRoute, {
      snapshot: { params: { id: 2 } }
    }));

    it('should have an id of 2', () => {
      renderComponent();
      expect(component.routeId).toEqual(2);
    });
  });
});

方案2:直接修改自定义mock对象

如果需要保留自行定义的mock对象,利用引用类型的特性直接修改属性值即可,不需要用到MockInstance:

const mockActivatedRoute = { snapshot: { params: { id: 1 } } };

describe('MyComponent', () => {
  beforeEach(() => {
    return MockBuilder(MyComponent, MyModule)
      .provide({ provide: ActivatedRoute, useValue: mockActivatedRoute })
  });

  function renderComponent() {
    fixture = MockRender(MyComponent);
    component = fixture.point.componentInstance;
  }

  it('should have an id of 1', () => {
    renderComponent();
    expect(component.routeId).toEqual(1);
  });

  describe('when it inits with a different id', () => {
    // 渲染前直接修改mock对象的属性
    beforeEach(() => {
      mockActivatedRoute.snapshot.params.id = 2;
    });

    it('should have an id of 2', () => {
      renderComponent();
      expect(component.routeId).toEqual(2);
    });
  });
});

补充说明

不需要将routeId设为public直接修改,这类跳过依赖注入逻辑的测试无法验证组件从ActivatedRoute获取参数的逻辑正确性,没有实际测试价值。


内容的提问来源于stack exchange,提问作者iamsar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 06:36:03