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

时间:2016-04-16 23:15:32

标签: 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);
    }
}

使用此模板(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>

和这个测试

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'
        });
    });
}));

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

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

谁能告诉我在这里缺少什么?

3 个答案:

答案 0 :(得分:7)

以防它可以帮助某人:

我已经能够使用By选择器和triggerHandle

在表单中触发提交事件
let form = fixture.debugElement.query(By.css('form'));
form.triggerEventHandler('submit', null);
fixture.detectChanges();
// your component function should have been called

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

答案 1 :(得分:5)

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

通过拨打&#39; click()&#39;我已成功解决了上述问题。本机元素的方法(不是调试元素)。请参阅下面的代码。请注意,在我的下面的代码中,我使用了ReactiveForms语法,但它不应该对测试产生影响。

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

在我的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();

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

答案 2 :(得分:2)

尝试在点击之前添加input_shape