Ric*_*key 4 jasmine karma-jasmine angular
我在测试一个 Angular 组件时遇到问题,该组件[(ngModel)]在ngFor. 它在实际应用中运行良好。这只是测试的问题。
这是一个失败的示例测试:
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { Component, EventEmitter, Output } from '@angular/core';
import { FormsModule } from '@angular/forms';
describe('Example Test', () => {
@Component({
template: `
<input *ngFor="let value of values"
type="checkbox"
class="checkbox-1"
[(ngModel)]="value.isSelected"
(change)="output.emit(values)">
`,
styles: [``]
})
class TestHostComponent {
@Output() output: EventEmitter<any> = new EventEmitter();
values = [
{ isSelected: true },
{ isSelected: true },
{ isSelected: true },
];
}
let testHost: TestHostComponent;
let fixture: ComponentFixture<TestHostComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [FormsModule],
declarations: [TestHostComponent],
providers: []
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TestHostComponent);
testHost = fixture.componentInstance;
fixture.detectChanges();
});
it('should change isSelected', fakeAsync(() => {
const spy = spyOn(testHost.output, 'emit');
fixture.nativeElement.querySelectorAll('.checkbox-1')[0].click();
fixture.detectChanges();
tick();
expect(spy).toHaveBeenCalledWith([
{ isSelected: false }, // it fails because this is still true
{ isSelected: true },
{ isSelected: true },
]);
}));
});
Run Code Online (Sandbox Code Playgroud)
[(ngModel)]在类似的测试中,使用不在循环中的单个输入可以正常工作。我甚至从记录的发射值(ngModelChange),并单击该复选框时$event是true当它真的应该false。
有任何想法吗?
似乎执行点击的方法不会触发更改检测。在复选框上调度更改事件反而给出了预期的结果:
it('should change isSelected', fakeAsync(() => {
const spy = spyOn(testHost.output, 'emit');
const checkbox = fixture.nativeElement.querySelectorAll('.checkbox-1')[0];
checkbox.dispatchEvent(new Event('change'));
fixture.detectChanges();
tick();
expect(spy).toHaveBeenCalledWith([
{ isSelected: false }, // This is now false
{ isSelected: true },
{ isSelected: true },
]);
}));
Run Code Online (Sandbox Code Playgroud)
受这篇文章启发的解决方案。
更新:
看起来需要等待一些控件在 CheckboxControlValueAccessor 上初始化或注册。如果beforeEach()在创建组件后修改第二个等待一个循环,则原始测试代码有效:
beforeEach(fakeAsync(() => {
fixture = TestBed.createComponent(TestHostComponent);
testHost = fixture.componentInstance;
fixture.detectChanges();
tick();
}));
Run Code Online (Sandbox Code Playgroud)
有关完整答案/解释,请参阅此 Github 问题。
| 归档时间: |
|
| 查看次数: |
2577 次 |
| 最近记录: |