如何测试子组件@output

时间:2019-06-18 04:38:08

标签: angular typescript unit-testing

我想在angular2中测试子组件@output。我想使用此模拟子组件@output激活父组件功能并对其进行测试。

模拟组件并测试所有异步方法。

<wizard-quick-search-page *ngIf="initSearchPanel" [createUserAttributes]="createUserAttributes" [existingUserAttributes]="existingUserAttributes" (edit)="showEditUserPanel($event)"
  (create)="showCreateUserPanel($event)">
</wizard-quick-search-page>
@Component({
  selector: 'wizard-quick-search-page',
  template: '<button class="quick-search-page-submit" (click)="onClick()">Create</button>'
})
class MockQuickSearchPageComponent {
  @Output() public create: EventEmitter<any> = new EventEmitter<any>();
  public onClick(): void {
    console.log('call create');
    this.create.emit(true);
  }
}

fdescribe('AddUserComponent', () => {
  let component: AddUserComponent;
  let fixture: ComponentFixture<AddUserComponent>;
  let mockQuickSearchComponent: MockQuickSearchPageComponent;
  let mockQuickSearchComponentFixture: ComponentFixture<MockQuickSearchPageComponent>;
  let createButton: DebugElement;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      providers: [
        { provide: Language, useClass: MockLanguage }
      ],
      declarations: [
        AddUserComponent,
        MockQuickSearchPageComponent
      ],
      schemas: [NO_ERRORS_SCHEMA]
    })
      .compileComponents();
  }));

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

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

  describe('quickSearchComponent', () => {
    beforeEach(() => {
      mockQuickSearchComponentFixture = TestBed.createComponent(MockQuickSearchPageComponent);
      mockQuickSearchComponent = mockQuickSearchComponentFixture.componentInstance;
      mockQuickSearchComponentFixture.detectChanges();

      createButton = mockQuickSearchComponentFixture.debugElement.query(By.css('button.quick-search-page-submit'));
    });

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

    it('should open create a new user panel', fakeAsync(() => {
      spyOn(component, 'showCreateUserPanel');
      createButton.triggerEventHandler('click', null);
      tick();
      mockQuickSearchComponentFixture.detectChanges();
      expect(component.showCreateUserPanel).toHaveBeenCalled();
    }));
  });
});

父组件函数component.showCreateUserPanel没有被调用

2 个答案:

答案 0 :(得分:0)

我创建了两个组件,并处理了子组件的输出事件。 您可以参考工作示例here

app.component.ts

import { Component,OnInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {
itemValue:number;
  name = 'Angular';
  ngOnInit(){
    this.itemValue=123;
  }
  showCreateUserPanel(value){
   console.log('showCreateUserPanel executed value',value);
  }
  showEditUserPanel(value){
   console.log('showEditUserPanel executed value',value);
  }
}

app.component.html

<p>
  parent component.
</p>
<app-child-component *ngIf="itemValue" [item]="itemValue" (createItem)="showCreateUserPanel($event)" (editItem)="showEditUserPanel($event)"></app-child-component>

child-component.ts

import { Component, OnInit,Input ,Output,EventEmitter} from '@angular/core';

@Component({
  selector: 'app-child-component',
  templateUrl: './child-component.component.html',
  styleUrls: ['./child-component.component.css']
})
export class ChildComponentComponent implements OnInit {
  @Input() item: any;
    @Output() createItem = new EventEmitter();
    @Output() editItem = new EventEmitter();
  constructor() { }

  ngOnInit() {
   console.log('item received',this.item);
  }
  create(){
      this.createItem.emit('123');
  }
   edit(){
      this.editItem.emit('123');
  }

}

child-component.html

<p>
  {{item}} received in child component.
  <button class="quick-search-page-submit" (click)="create()">Create</button>
   <button class="quick-search-page-submit" (click)="edit()">Edit</button>
</p>

答案 1 :(得分:0)

如果要测试父子之间的通信方式,则不应创建MockQuickSearchPageComponent的隔离实例,而应使用在父组件中初始化的实例。

当前测试

AddUserComponent  MockQuickSearchPageComponent

在您的实现中,他们彼此之间一无所知。

  

TestBed.createComponent(MockQuickSearchPageComponent); 使用MockQuickSearchPageComponent作为根组件创建新的组件树

应如何做

 AddUserComponent  
       ||
       \/
MockQuickSearchPageComponent

现在MockQuickSearchPageComponentAddUserComponent的子级,可以监听该子级组件发出的任何事件。

可以通过使用fixture.debugElement.query(By.directive(MockQuickSearchPageComponent)来完成:

describe('quickSearchComponent', () => {
  beforeEach(() => {
    fixture.componentInstance.initSearchPanel = true;
    fixture.detectChanges();

    const childDirQueryResult = 
             fixture.debugElement.query(By.directive(MockQuickSearchPageComponent));

    mockQuickSearchComponent = childDirQueryResult.componentInstance;

    createButton = childDirQueryResult.query(By.css('button.quick-search-page-submit'));
  });

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

  it('should open create a new user panel', () => {
    spyOn(component, 'showCreateUserPanel');
    createButton.triggerEventHandler('click', null);

    expect(component.showCreateUserPanel).toHaveBeenCalled();
  });
});

Plunker Example