4

Angular2 で双方向バインディングをテストするためのドキュメントを読みました。実際、すべての例は単純で、単純すぎます。

彼らはアウトバインディングのみをテストしているようです...

説明するためにいくつかのコードを投稿します。

import { Component, Input } from "@angular/core";
import { ComponentFixture, async, TestBed, tick, fakeAsync } from 
"@angular/core/testing";
import { FormsModule } from "@angular/forms";
import { By } from "@angular/platform-browser";

@Component({
    selector: 'test',
    template: `
        <input type="text" [(ngModel)]="myValue" />
        <div>{{ myValue }}</div>
    `
})
class TestComponent {
    @Input() myValue: string
}

describe('Example', () => {
    let component: TestComponent
    let fixture: ComponentFixture<TestComponent>

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [TestComponent],
            providers: [],
            imports: [FormsModule]

        })
            .compileComponents()
    }))

    beforeEach(() => {
        fixture = TestBed.createComponent(TestComponent)
        component = fixture.componentInstance

        fixture.detectChanges()
    })

    it('should test two-way binding by setting the component member', 
        fakeAsync(() => {

            const testValue = 'Component member test'

            component.myValue = testValue // Should be the correct way to 
            test ngModel

            tick();
            fixture.detectChanges();

            // Assertion error: Expected '' to equal 'Component member test'
            // Why wasn't the value set in the textbox?
            expect(fixture.debugElement.query(By.css('input'))
.nativeElement.value).toEqual(testValue)

            //Yeah, the bananas are working. We have out-binding
            expect(fixture.debugElement
                .query(By.css('div'))
                .nativeElement
                .textContent
            ).toEqual(testValue);
    }))

    it('should test two-way binding by setting value directly on the native 
element. But that just tests the out-binding', fakeAsync(() => {
            const testValue = 'NativeElement test'

            let element = 
fixture.debugElement.query(By.css('input')).nativeElement;
            element.value = testValue // this tests only the out-binding
            element.dispatchEvent(new Event('input'));

            tick();
            fixture.detectChanges();

            //of course this is Ok, we just set it directly
            expect(fixture.debugElement.query(By.css('input'))
.nativeElement.value).toEqual(testValue)

            //Yeah, the bananas are working. We have out-binding
            expect(fixture.debugElement
                .query(By.css('div'))
                .nativeElement
                .textContent
            ).toEqual(testValue);
    }))
})

myValue を設定してコンポーネントを実際にテストする方法はありますか? 私は何かが欠けていると思います...

4

2 に答える 2

8

2行を入れ替えてみてください:

tick();
fixture.detectChanges();

だからそうあるべきだ

fixture.detectChanges();
tick();

これは、最初に値を設定する必要があることを意味し、角度が制御値を更新している間待機する必要があります。これは内部で発生するためですPromise.then

https://github.com/angular/angular/blob/4.1.0-rc.0/packages/forms/src/directives/ng_model.ts#L213-L214

プランカーの例

于 2017-04-26T12:30:29.663 に答える
0

HTML 入力タグに name 属性を追加する必要があります

<input type="text" [(ngModel)]="myValue" name="myValue"/>
于 2017-04-26T12:10:13.640 に答える