如何编写一个检查父组件属性的测试用例?

时间:2017-09-29 09:36:13

标签: angular jasmine karma-runner karma-jasmine

父组件:

export class PlayerListComponent {
  flag = false;
}

子组件:

export class PlayerAddComponent {
  @Output() notifyParent: EventEmitter<any> = new EventEmitter();

  clkCancle() {
    this.notifyParent.emit(false);
    // this will set parent component property 'flag' to false.
  }
}

现在我如何在Jasmine规范文件中编写测试用例?

it('cancel button click should set flag to false', function () {
  // Act
  component.clkCancle();

  // Assert 
  // Since component do not have flag property. It will be set in parent while by Emitter.
  expect(???).toBe(false);
});

1 个答案:

答案 0 :(得分:-3)

要同时测试两个组件,您必须在同一个TestBed中加载两个组件。例如:

describe('component interaction', () => {
  let fixture: ComponentFixture<PlayerListComponent>;
  let component: PlayerListComponent;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [PlayerListComponent, PlayerAddComponent],
    }).compileComponents();
  }));

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

  it('should set the parent flag when the child method is called', () => {
    // Arrange
    const child: PlayerAddComponent = fixture.debugElement
      .query(By.directive(PlayerAddComponent))
      .componentInstance;

    // Act
    child.clkCancle();  // ...Cancel?
    fixture.detectChanges();

    // Assert
    expect(component.flag).toBe(false, 'parent flag should be set');
  }
});

否则,你应该只测试孩子在正确的时间排出,因为它不应该成为孩子责任的一部分,因为这样做会发生这种情况(这种行为可能会在没有孩子的情况下发生变化被改变,或根据孩子的使用位置而有所不同):

it('should emit when the method is called', done => {
  component.clkCancle();  // here component is PlayerAddComponent

  component.notifyParent.subscribe(flag => {
    expect(flag).toBe(false, 'should emit false');
    done();
  });
});

请注意,在这两种情况下,我都建议您在点击按钮时使用例如进行测试。 fixture.nativeElement.querySelector('...').click();,而不是在调用方法时;这有助于将行为实现分开,从而允许您重命名内部方法,而无需更新测试。