Angular2测试表单:提交方法未调用

Fra*_*čik 2 javascript unit-testing angular

有这个组件

import {Component} from 'angular2/core';
import { FORM_DIRECTIVES } from 'angular2/common';

@Component({
    selector: 'something',
    templateUrl: 'something.html',
    providers: [],
    directives: [FORM_DIRECTIVES],
    pipes: []
})
export class Something {

    constructor() { }

    save(data) {
        alert(data);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用此模板(something.html)

<form #myForm="ngForm" (ngSubmit)="save(myForm.value)">
    <label for="title">Title</label>
    <input id="title" type="text" ngControl="title" />

    <label for="primaryImage">Primary Image</label>
    <input id="primaryImage" type="text" ngControl="primaryImage" />

    <button type="submit">Save</button>
</form>
Run Code Online (Sandbox Code Playgroud)

而这个测试

it('should call save method after clicking a Save button', injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
    return tcb.createAsync(Something).then((fixture) => {
        spyOn(fixture.componentInstance, 'save');
        fixture.detectChanges();
        const compiled = fixture.nativeElement;
        compiled.querySelector('#title').value = 'testTitle';
        compiled.querySelector('#primaryImage').value = 'tabc.png';                   
        compiled.querySelector('button').click();
        expect(fixture.componentInstance.save).toHaveBeenCalledWith({
            title: 'testTitle',
            primaryImage: 'abc.png'
        });
    });
}));
Run Code Online (Sandbox Code Playgroud)

测试失败,没有在间谍上调用save方法.但是,当我在浏览器中手动尝试时,如果有效,则会显示警报.当我执行form.submit时,测试也会失败,而不是button.click.

当我(click)="save(myForm.value)"在按钮而不是ngSubmit表单上使用时,测试仍然失败,但原因是不同的.在这种情况下已经调用了spy上的save方法,但传递给它的数据是{}.

谁能告诉我,我在这里失踪了什么?

Jua*_*uez 7

以防它可以帮助某人:

我已经能够使用By选择器和triggerHandle触发表单中的提交事件

let form = fixture.debugElement.query(By.css('form'));
form.triggerEventHandler('submit', null);
fixture.detectChanges();
// your component function should have been called
Run Code Online (Sandbox Code Playgroud)

如果您尝试触发按钮中的单击事件,则它似乎不会触发ngSubmit.如果您尝试在表单上执行.submit,则不会被agular捕获并刷新页面.


Jea*_* A. 7

要添加Juanmi的答案以使测试完全完成,必须通过单击按钮触发事件,因为例如,如果按钮移出标记,应用程序将失败,但测试仍将通过.

我已经成功解决了上面的问题,通过调用本机元素的"click()"方法(而不是调试元素).请参阅下面的代码.请注意,在我下面的代码中,我使用的是ReactiveForms语法,但它不会对测试产生影响.

<form [formGroup]="sampleForm" (submit)="submit($event)">
    <input id="sampleBtn" type="submit" class="btn-default btn btn-primary" value="Click Me">
</form>
Run Code Online (Sandbox Code Playgroud)

在我的spec.ts文件中

spyOn(fixture.componentInstance, 'submit');
let loginBtn: DebugElement = fixture.debugElement.query(By.css('#sampleBtn'));
loginBtn.nativeElement.click();
fixture.detectChanges();
expect(fixture.componentInstance.submit).toHaveBeenCalled();
Run Code Online (Sandbox Code Playgroud)

按钮上的这个click()将依次触发(提交)处理函数.希望这可以帮助.:)