使用@ViewChild单元测试角度5组件

时间:2018-07-25 09:32:17

标签: angular unit-testing viewchild testbed

我正在使用角度5.2.0。我有一个子组件

cxt.drawRectangle(x,y,width,height,{type: 'stroke',
       color: '#eeeeee',
       opacity: 0.9});  

和一个通过import { Component } from '@angular/core'; @Component({ template: `<div><\div>` }) export class ChildComponent { public childMethod() { ... } }

访问子级的父级组件
ViewChild

我想要一个单元测试,证明调用import { Component, ViewChild } from '@angular/core'; import { ChildComponent } from 'child.component'; @Component({ template: `<child-component #child><\child-component>` }) export class ParentComponent { @ViewChild('child') public child: ChildComponent; public parentMethod() { this.child.childMethod(); } } 会导致调用parentMethod。我有以下内容:

childMethod

但是,这不起作用,我得到了import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ChildComponent } from './child.component'; import { ParentComponent } from './parent.component'; describe('ParentComponent', () => { let component: Parentcomponent; let fixture: ComponentFixture<Parentcomponent>; beforeEach(() => { TestBed.configureTestingModule({ declarations: [ ParentComponent, ChildComponent ], schemas: [ NO_ERRORS_SCHEMA ] }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(TaskListPaginatorComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should invoke childMethod when parentMethod is invoked', () => { const childMethodSpy: jasmine.Spy = spyOn(component.child, 'childMethod'); component.parentMethod(); expect(childMethodSpy).toHaveBeenCalled(); }); });

此外,这不是单元测试,因为我使用了真正的ChildComponent而不是模拟对象。我尝试创建一个MockChildComponent并将其添加到Error: <spyOn> : could not find an object to spy upon for childMethod()declarations中,但是得到了相同的结果。有帮助吗?

我知道也有类似的帖子,但是它们适用于不同版本的angular,它们并没有帮助。

1 个答案:

答案 0 :(得分:8)

您可以执行以下操作。

像这样为ChildComponent创建一个间谍对象。

const childComponent = jasmine.createSpyObj('ChildComponent', ['childMethod']);

然后在测试中将组件的子组件属性设置为您创建的间谍。

  component.childComponent =  childComponent;

您的测试文件应该这样。

import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ChildComponent } from './child.component';
import { ParentComponent } from './parent.component';

describe('ParentComponent', () => {

    let component: Parentcomponent;
    let fixture: ComponentFixture<Parentcomponent>;

    const childComponent = jasmine.createSpyObj('ChildComponent', ['childMethod']);

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [ ParentComponent, ChildComponent ],
            schemas: [ NO_ERRORS_SCHEMA ]
    }).compileComponents();
});

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

    it('should invoke childMethod when parentMethod is invoked', () => {
        component.childComponent =  childComponent;
        component.parentMethod();
        expect(childComponent.childMethod).toHaveBeenCalled();
    });

});