订阅ActivatedRoute数据时如何对调用的函数进行单元测试?

问题描述 投票:0回答:1

我想在Angular应用中对组件的ngOnInit()方法进行单元测试。 ngOnInit()方法订阅ActivatedRoute data,并在subscribe方法内部调用一个函数。这是该方法的代码:

component.ts

ngOnInit() {
  this.route.data.subscribe(data => this.store.patchState(data));
}

这是我的测试:

component.spec.ts

beforeEach(() => {
    fixture = TestBed.createComponent(xyzComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

it('#ngOnInit should call patchState', async(() => {

    const spy = spyOn(store, 'patchState');

    // When
    component.ngOnInit();

    fixture.detectChanges();

    // Then
    expect(spy.calls.count()).toBe(1, 'patchState has been called once.');

  }));

但是,当我运行测试时,出现一个错误,告诉我'从未调用过预期的间谍patchState。'

我相信我的问题来自测试的异步性质,但我不知道为什么它不起作用。

我在这里做错了什么?

谢谢!

angular unit-testing jasmine observable angular2-routing
1个回答
0
投票

将订阅更改为:

this.route.data.subscribe(data => {
                                   console.log('in route subscription);
                                   this.store.patchState(data)
                         });

如果没有看到console.log('in route subscription'),则可能是您没有正确嘲笑activatedRoute

尝试一下:

describe('xyzComponent', () => {
  let store: Store<...>; // for you to fill out
  let component: xyzComponent;
  let fixture: ComponentFixture<xyzComponent>;
  let data$ = new BehaviorSubject({ x: 1 }); // mock data for activatedRoute

  beforeEach(async() => {
    TestBed.configureTestingModule({
      imports: [ StoreModule.forRoot(....) ], // for you to fill out
      declarations: [ XYZComponent ],
      providers: [
        { provide: ActivatedRoute, useValue: { data: data$ } },
      ],
    }).compileComponents();
  });

  beforeEach(() => {
    store = TestBed.get(store);
    spyOn(store, 'patchState').and.callThrough(); // and.callThrough() is optional, do you want it to HAVE both a spy and call the actual implementation?
    fixture = TestBed.createComponent(xyzComponent);
    component = fixture.componentInstance;
    fixture.detectChanges(); // this fixture.detectChanges() will call `ngOnInit` for us, so we don't have to manually call it
  });

  it('ngOnInit should call patchState', () => {
    expect(store.patchState).toHaveBeenCalledWith({ x: 1 });
  });
});

希望可以使您畅通无阻。您也可以在以后的测试中更改route.data,并通过执行data.next$({....})您的未来值来查看其反应。

© www.soinside.com 2019 - 2024. All rights reserved.