角度单位测试输入值

我一直在阅读 Angular2的单元测试官方文档(https://angular.io/docs/ts/latest/guide/testing.html) ,但是我正在努力设置一个组件的输入字段值,使其反映在组件属性中(通过 ngModel 绑定)。屏幕在浏览器中工作良好,但在单元测试中,我似乎不能设置字段值。

我使用以下代码。当其他测试正常工作时,“ fixture”被正确初始化。“ comp”是我的组件的实例,输入字段通过 ngModel 绑定到“ user.username”。

it('should update model...', async(() => {
let field: HTMLInputElement = fixture.debugElement.query(By.css('#user')).nativeElement;
field.value = 'someValue'
field.dispatchEvent(new Event('input'));
fixture.detectChanges();


expect(field.textContent).toBe('someValue');
expect(comp.user.username).toBe('someValue');
}));

我的版本 Angular2: "@angular/core": "2.0.0"

119594 次浏览

输入没有 textContent,只有一个值。所以 expect(field.textContent).toBe('someValue');是没用的。这可能就是失败的原因。不过,第二个期望应该会过去。这是一个完整的测试。

@Component({
template: `<input type="text" [(ngModel)]="user.username"/>`
})
class TestComponent {
user = { username: 'peeskillet' };
}


describe('component: TestComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [FormsModule],
declarations: [ TestComponent ]
});
});


it('should be ok', async(() => {
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
fixture.whenStable().then(() => {
let input = fixture.debugElement.query(By.css('input'));
let el = input.nativeElement;


expect(el.value).toBe('peeskillet');


el.value = 'someValue';
el.dispatchEvent(new Event('input'));


expect(fixture.componentInstance.user.username).toBe('someValue');
});
}));
});

重要的部分是第一个 fixture.whenStable()。有一些异步设置的形式发生,所以我们需要等待,以完成后,我们做 fixture.detectChanges()。如果您使用的是 fakeAsync()而不是 async(),那么您只需在 fixture.detectChanges()之后调用 tick()即可。

只要加上

fixture.detectChanges();


fixture.whenStable().then(() => {
// here your expectation
})

whenStable.then函数中使用预期/断言,如下所示:

component.label = 'blah';
fixture.detectChanges();


fixture.whenStable().then(() => {
expect(component.label).toBe('blah');
}

如果您希望使用@Input 内容实现单元测试,那么请执行下面的代码。

Testing.Component. ts

    import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-testing',
templateUrl: `<app-input [message]='text'></app-input>`,
styleUrls: ['./testing.component.css']
})
export class TestingComponent implements OnInit {
public text = 'input message';
constructor() { }
    

ngOnInit() {
}
    

}

Input.Component. ts

    import { Component, OnInit, Input } from '@angular/core';
    

@Component({
selector: 'app-input',
templateUrl: `<div *ngIf="message">\{\{message}}</div>`,
styleUrls: ['./input.component.css']
})
export class InputComponent implements OnInit {
@Input() public message: string;
constructor() { }
    

ngOnInit() {
console.log(this.message);
}
    

}

Spec.ts

    import { async, ComponentFixture, TestBed } from '@angular/core/testing';
    

import { InputComponent } from './input.component';
import { TestingComponent } from '../testing/testing.component';
    

describe('InputComponent', () => {
let component: InputComponent;
let fixture: ComponentFixture<InputComponent>;
    

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ InputComponent, TestingComponent ]
})
.compileComponents();
}));
    

beforeEach(() => {
fixture = TestBed.createComponent(InputComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
    

it('should create', () => {
expect(component).toBeTruthy();
});
    

it('should correctly render the passed @Input value', () => {
component.message = 'test input';
fixture.detectChanges();
expect(fixture.nativeElement.innerText).toBe('test input');
});
    

});