I would like to test a child component @output in angular2. I want to use this mock child component @output to activate a parent component function and test it.
Mock the component and test all the async method.
<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();
}));
});
});
Parent component function component.showCreateUserPanel not been called
@Input() and @Output() give a child component a way to communicate with its parent component. @Input() lets a parent component update data in the child component. Conversely, @Output() lets the child send data to a parent component.
If you want to test how parent and child communicate to each other then you shouldn't create isolated instance of MockQuickSearchPageComponent
but rather use the instance which is initialized within parent component.
Current test
AddUserComponent MockQuickSearchPageComponent
In your implementation they know nothing about each other.
TestBed.createComponent(MockQuickSearchPageComponent); creates a new component tree with MockQuickSearchPageComponent as a root component
How it should be done
AddUserComponent
||
\/
MockQuickSearchPageComponent
Now MockQuickSearchPageComponent
is a child of AddUserComponent
and can listen for any events emmited from that child component.
It could be done by using 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With