如何在Angular Component中编写ActionsSubject订阅的单元测试

时间:2019-08-24 23:27:33

标签: angular unit-testing testing jasmine ngrx

我有一个Angular组件,它使用ngrx ActionsSubject侦听调度的动作。如何编写可以检查对此ActionsSubject的订阅的测试?

该组件如下所示:

export class TestComponent {

constructor(public actionsSubject: ActionsSubject) { }

  public isUpdated = false;

  public ngOnInit() {
    this.actionSubscription = this.actionsSubject.subscribe(action => {
      if (action.type === "Update") {
        this.isUpdated = true; <----- I want to test this condition
      }
    });
  }
}

当前,我正在手动调度更新操作:

  it('isUpdated should be true, when update action dispatched', () => {
    component.store.dispatch(new UpdateAction());
    expect(component.isUpdated).toEqual(true);
  });

它可以工作,但是我想模拟该订阅,而不是手动调用操作。

例如:

  it('isUpdated should be true, when update action dispatched', () => {
    let actionSubject = TestBed.get(ActionsSubject);
    const action = {
      type: 'Update'
    };
    actionSubject = of({ action });
    component.ngOnInit();
    fixture.detectChanges()
    expect(component.isUpdated).toEqual(true);
  });

测试服看起来像这样

const action = { type: FlowActionTypes.UpdateStep }; 
const actionSub: ActionsSubject = new ActionsSubject({ action }); <-- TS not accepting 


providers: [ { provide: ActionsSubject, useValue: actionSub } <-- here I am passing as you told ] 

但是它永远不会触发组件中的订阅。如何有效测试?

1 个答案:

答案 0 :(得分:2)

您就近在咫尺! 一些可以帮助您的事情:

  • ngOnInit在您第一次调用fixture.detectChanges时运行(在本例中为beforeEach),因此无需在测试中再次调用
  • ActionsSubject继承自BehaviorSubject,因此您可以将其视为任何其他可观察的对象
  • fixture.detectChanges更新测试中的html,因为您直接查看组件上的变量,所以无需调用
  • TestBed.get返回any,有助于将其转换为您想要的服务
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { TestComponent } from './test.component';
import { ActionsSubject } from '@ngrx/store';

describe('TestComponentComponent', () => {
  let component: TestComponent;
  let fixture: ComponentFixture<TestComponent>;

  beforeEach(async(() => {
    const actionSub: ActionsSubject = new ActionsSubject();

    TestBed.configureTestingModule({
      declarations: [TestComponent],
      providers: [{ provide: ActionsSubject, useValue: actionSub }],
    })
      .compileComponents();
  }));

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

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  fit('isUpdated should be true, when update action dispatched', () => {
    const actionSubject = TestBed.get(ActionsSubject) as ActionsSubject;
    const action = {
      type: 'Update'
    };
    actionSubject.next(action);

    expect(component.isUpdated).toEqual(true);
  });
});