web-dev-qa-db-ja.com

単体テストangular 5コンポーネント@ViewChild

angular 5.2.0を使用しています。子コンポーネントがあります。

_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();
    });

});
_

しかし、これは機能せず、Error: <spyOn> : could not find an object to spy upon for childMethod()を取得します。

さらに、モックではなく実際のChildComponentを使用しているため、これは単体テストではありません。 MockChildComponentを作成してdeclarationsexportに追加してみましたが、同じ結果が得られました。何か助け?

同様の投稿があることは知っていますが、それらは異なるバージョンのangular用であり、助けにはなりませんでした。

11
Jacopo Lanzoni

このようなことができます。

このように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();
    });

});
4