ActivatedRoute 的 Jasmine 测试 Angular 7

Jasmine test for ActivatedRoute Angular 7

我正在尝试为 ActivatedRoute 编写一个简单的测试。这是我的测试结果。

it("should check if subscribes are called in init", () => {
    const subRouteSpy = spyOn(activatedRouteStub.paramMap, "subscribe");
    component.ngOnInit();
    expect(subRouteSpy).toHaveBeenCalled();
});

我的TestBed config:

const activatedRouteStub = {
  paramMap: {
    subscribe() {
      return of();
    }
  }
};

TestBed.configureTestingModule({
  declarations: [HomeFilterDrawerComponent],
  providers: [
    { provide: ActivatedRoute, useValue: activatedRouteStub }
  ],
  imports: [
    FormsModule,
    StoreModule.forRoot(appReducers),
    HttpClientTestingModule,
    RouterTestingModule
  ]
}).compileComponents();

测试一直失败给我 Expected spy subscribe to have been called. 不确定我到底做错了什么。

组件ngOnInit里面的代码。

this.route.paramMap.subscribe(params => {
  if (params["params"].slug !== undefined) {
  }
});
当您通过 useValue 提供对象时,

Angular 正在克隆您的 activatedRouteStub 对象。因此,您正在监视原始存根对象,但您的组件看到了一个没有附加间谍的克隆对象。

这是mentioned in the guide

Always get the service from an injector Do not reference the userServiceStub object that's provided to the testing module in the body of your test. It does not work! The userService instance injected into the component is a completely different object, a clone of the provided userServiceStub.

要解决此问题,您需要使用 TestBed.get

获取对克隆对象的引用
let activatedRoute;

const activatedRouteStub = {
  paramMap: {
    subscribe() {
      return of();
    }
  }
};

TestBed.configureTestingModule({
  declarations: [HomeFilterDrawerComponent],
  providers: [
    { provide: ActivatedRoute, useValue: activatedRouteStub }
  ],
  imports: [
    FormsModule,
    StoreModule.forRoot(appReducers),
    HttpClientTestingModule,
    RouterTestingModule
  ]
}).compileComponents();

beforeEach(() => {
  fixture = TestBed.createComponent(NewsComponent);
  component = fixture.componentInstance;

  // Get a reference to the injected value
  activatedRoute = TestBed.get(ActivatedRoute);
});

it("should check if subscribes are called in init", () => {
  // Spy on the injected value
  const subRouteSpy = spyOn(activatedRoute.paramMap, "subscribe");
  component.ngOnInit();
  expect(subRouteSpy).toHaveBeenCalled();
});

或者,您可以保持代码不变,但将 useValue 更改为 useFactory。这将允许您绕过克隆行为:

providers: [{ provide: ActivatedRoute, useFactory: () => activatedRouteStub }]