输出绑定最简单的测试不起作用

时间:2019-05-30 07:10:38

标签: angular typescript unit-testing

我正在用一个按钮测试一个失效的简单组件。单击按钮时,它发出一个{PERSIST, MERGE}事件,然后调用父级的回调(@OneToMany List<DimensionalCondition>)。没有什么不寻常的。

但是由于某些原因,以下测试无法正常工作。我只是测试单击孩子的(@output)时是否调用了父母的chatMessageFeedbackHandler

注意:如果您评论以下任何一项测试均能成功进行:

  1. LINE:孩子1.1和孩子1.2
  2. LINE:父级1.1和父级1.2

测试:

chatMessageFeedbackHandler

子组件:

button#test1

1 个答案:

答案 0 :(得分:0)

要测试以下父宿主组件,请在子对象发出信号时调用实际函数,我认为您是从错误的角度解决问题。

在您的情况下,您需要模拟模板组件(子组件,即app-chat-feedback组件),并手动触发事件触发(不是通过整个单击过程,对于另一个单元测试就是这种情况)。检查以下内容,这应该可以使您工作。

这是模板组件的模拟

@Component({
    template: '',
    selector: 'app-chat-feedback'
})
export class ChatFeedbackComponentMock {


    @Output() chatMessageFeedback$: EventEmitter<any> = new EventEmitter<any>();

    // This will be the function that triggers the emit
    emitFeedback(value: any) {
        this.chatMessageFeedback$.emit(value);
    }
}

这是您要测试其功能的组件,在这种情况下,当孩子发出事件时将调用chatFeedbackClicked。这才是真正的组成部分。

@Component({
    template:`
        // Your Logic here
        <app-chat-feedback (chatMessageFeedback$)="chatFeedbackClicked($event)"></app-chat-feedback>
    `
})
export class MyComponentUnderTest {
    chatFeedbackClicked() {
        // Your logic here
    }
}

这是测试定义。

describe('MyComponentUnderTest', () => {

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

    beforeEach(() => {
        // Register both the real component under test, and the mock component of the child
        TestBed.configureTestingModule({
            declarations: [ ChatFeedbackComponentMock, MyComponentUnderTest]
        });

        // Get a handle to the component fixture, and the component instancce
        fixture = TestBed.createComponent(MyComponentUnderTest);
        component = fixture.componentInstance;
    });

    // Important that you have the fakeAsync wrapper function, since the EventEmmiter behaves asynchronously
    it('Should call chatFeedbackClicked when the chatMessageFeedback$ event is fired', fakeAsync(() => {

        // Get a handle of the instance of the child mock component (the template component that you're mocking)
        let child: ChatFeedbackComponentMock = fixture.debugElement.query(By.css('app-chat-feedback')).componentInstance;  

        // Spy on the function of the component under test, that will be asserted
        spyOn(component, 'chatFeedbackClicked');

        // Call emit feedback with some value, on the child component. This will trigger an emit call
        child.emitFeedback('value');

        // Since the calls are asynchronous, (EventEmmitter behaves like an observable), we need to simulate passing of time
        tick();

        // Assert that the function was called with the passed value
        expect(component.chatFeedbackClicked).toHaveBeenCalledWith('value');
    }));
});

详细了解有关测试异步功能here和有关fakeAsync包装函数here的信息