问题描述
我有一个搜索输入字段,该输入字段会在键入值后立即调用组件方法(“ searchBooks”)。
html :
<form [formGroup]="searchForm">
<mat-form-field>
<input matInput type="search" formControlName="term"/>
</mat-form-field>
</form>
组件:
export class BookSearchComponent implements OnInit {
searchForm = this.fb.group({
term: ''
});
...
ngOnInit() {
this.searchForm.get('term').valueChanges
.subscribe(() => this.searchBooks()); // this subscription will listen to any value changes on the input field
}
searchBooks() {
// does something
}
我正在尝试编写一个单元测试,以检查在输入字段中输入值后是否调用了“ searchBooks”方法。当我尝试以下尝试时,测试永远不会达到断言
:规格文件:
describe('Search for Books',() => {
let component: BookSearchComponent;
let fixture: ComponentFixture<BookSearchComponent>;
let searchInputField: ElementRef;
let searchBooks: jasmine.Spy;
beforeEach(async(() => {
Testbed.configureTestingModule({
imports: [BooksFeatureModule,NoopAnimationsModule,SharedTestingModule]
}).compileComponents();
component = fixture.componentInstance;
fixture = Testbed.createComponent(BookSearchComponent);
searchInputField = fixture.debugElement.query(By.css('input'));
searchBooks = spyOn(component,'searchBooks');
fixture.detectChanges();
}));
...
it('searchBooks method should be called after a value is entered in the search field',() => {
searchInputField.nativeElement.value = 'Harry Potter';
searchInputField.nativeElement.dispatchEvent(new Event('input'));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.searchBooks).toHaveBeenCalled(); // <--- Test runner never gets to this assertion!
});
});
对测试上述行为的实用方法有何建议? (在输入字段中输入值会触发searchBooks方法)
解决方法
我认为您需要利用<ButtonMailto label="Write me an E-Mail" mailto="mailto:no-reply@example.com" />
回调来让Angular / Jasmine知道何时完成测试。它不会进入done
块中,因为它是异步的,并且测试将在回调发生之前完成。
尝试:
then
您也可以以it('searchBooks method should be called after a value is entered in the search field',(done) => { // add done call back as argument
searchInputField.nativeElement.value = 'Harry Potter';
searchInputField.nativeElement.dispatchEvent(new Event('input'));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.searchBooks).toHaveBeenCalled(); // <--- Test runner never gets to this assertion!
done(); // call done letting jasmine know I am done with my assertions
});
});
的方式进行操作(我更喜欢这样):
async/await
此外,由于您使用的是反应形式,因此反应形式的主要支持者是简化测试。您可以使用JavaScript设置表单的值并进行断言,而不必弄乱DOM。
it('searchBooks method should be called after a value is entered in the search field',async () => { // add async here
searchInputField.nativeElement.value = 'Harry Potter';
searchInputField.nativeElement.dispatchEvent(new Event('input'));
fixture.detectChanges();
await fixture.whenStable(); // wait until the fixture is stable
expect(component.searchBooks).toHaveBeenCalled(); // <--- Test runner never gets to this assertion!
});