Как протестировать вызов функции, вызываемой при подписке на данные ActivatedRoute? - PullRequest
0 голосов
/ 12 февраля 2020

Я хочу провести модульное тестирование метода ngOnInit () компонента в моем приложении Angular. Метод ngOnInit () подписывается на ActivatedRoute data и вызывает функцию внутри метода подписки. Вот код метода:

component.ts

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

Вот мой тест:

component.spe c .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 никогда не вызывался».

Я полагаю, что моя проблема связана с асинхронный характер теста, но я не могу понять, почему он не будет работать.

Что я здесь не так делаю?

Спасибо!

1 Ответ

0 голосов
/ 14 февраля 2020

Измените подписку на:

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$({....}) ваше будущее значение.

...