angular - 在反应式表单模块的 auditTime 方法的订阅块中测试值
问题描述
我正在尝试在.subscribe
使用方法的 angular4/typescript jasmine 单元测试中测试块内的值rxjs auditTime
。我已经阅读了很多与此类似的帖子,这些帖子似乎并没有让我进入那个街区。
我有以下示例组件:
地址.component.ts:
export class AddressComponent implements OnInit {
public form: FormGroup;
constructor (
private fb: FormBuilder
) {}
public ngOnInit (): void {
this.createForm();
}
public createForm (): void {
this.form = this.fb.group({
lineOne: [this.address.lineOne],
});
this.form.valueChanges.auditTime(500).subscribe(() => {
this.address.lineOne = this.form.value.lineOne;
});
}
}
地址.component.html:
<div class="address">
<form [formGroup]="form">
<div class="row">
<div class="col-12 address-body">
<div class="form-group-main">
<div class="row">
<div class="address-input col-12">
<label for="address-line-one" [class.required]="isMandatory">Address Line 1</label>
<input class="form-control" id="address-line-one" type="text" formControlName="lineOne">
</div>
</div>
</div>
</div>
<div class="col-12 address-body">
<display-address [body]="address.lineOne"></display-address>
</div>
<div class="col-12">
<button class="btn btn-full-width btn-primary btn-sm btn-edit" id="address-edit" type="button" (click)="...">Edit</button>
</div>
</div>
</form>
</div>
地址.component.spec.ts:
describe('Address Component', () => {
let component: AddressComponent;
let fixture: ComponentFixture<AddressComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AddressComponent],
imports: [ReactiveFormsModule],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents().then(() => {
fixture = TestBed.createComponent(AddressComponent);
component = fixture.componentInstance;
});
}));
it('should update address', fakeAsync(() => {
component.address = {lineOne: 'street'};
fixture.detectChanges();
//do something..
}));
});
假设上述设置正确,并且我没有错过明显的东西,这就是为什么我的测试从未提供正确结果的原因,我尝试使用以下想法修改我的测试:
监视 auditTime 并通过以下方式调用:
spyOn(component.form.valueChanges, 'auditTime').and.callThrough();
监视 auditTime 并调用假函数:
spyOn(component.form.valueChanges,'auditTime').and.callFake(()=> {
return {
subscribe: () => {}
}
});
监视 auditTime 并返回一个值 Observable.of:
spyOn(component.form.valueChanges,'auditTime').and.returnValue(Observable.of('hello'));
直接调用它:
component.form.valueChanges.auditTime().subscribe(result => {
//never get in here
});
试图等待 using:tick()
并试图刷新 using: flushMicrotasks()
。
监视 createForm 函数:
spyOn(component, 'createForm').and.callFake(() => {
return Observable.of('hello');
});
如果我使用以下内容,使用 debugElement 访问和更新 lineOne 总是返回错误:
const el = fixture.nativeElement.querySelector(By.css('#address-line-one'));
el.value = 'something';
el.dispatchEvent(new Event('input'));
fixture.detectChanges();
因为它看起来只能看到 html 和 的编辑按钮<display-address></display-address>
,这表明它当时可能没有编译。
我还尝试将所有内容包装在:
fixture.whenStable().then(() => {
// do something..
});
现在我没有想法了,如果有人能理解上述内容并指出我正确的方向,那就太好了..
解决方案
多亏了 Amir,在这个特定的例子中,我似乎过度思考了所需的答案,并且使用NO_ERRORS_SCHEMA
隐藏了真正的问题。事实证明我需要导入需要的组件<display-address>
:
imports: [ReactiveFormsModule, DisplayAddressComponent],
这允许模板正确编译,这意味着我可以看到所有表单值,而不仅仅是<display-address>
. 按照建议,我使用 和 的组合fakeAsync
来tick(600)
对表单进行更改:
it('should update address', fakeAsync(() => {
component.address = {lineOne: 'street'};
fixture.detectChanges();
expect(component.address.lineOne).toBe('street');
component.form.controls['lineOne'].setValue('test');
tick(600);
expect(component.address.lineOne).toBe('test');
}));
只是如果有人有类似的问题。
解决方案
好的,我将在这里发布我的假设,检查它是否有帮助:
- 创建组件后直接调用 ngOnInit()或 使用detectChanges() ;
- 仅当您使用fakeAsync + tick(600);时,测试才应该同步工作;
- 执行tick(600)后尝试将值发射到this.form.valueChanges中,您可以通过替换 FormBuilder来做到这一点,这样它将使用您自己的发射器(主题)返回对象,或者通过在 html 中查找元素并使用 DOM 事件输入值.
- 如果您决定使用 html 作为 input,请删除 NO_ERRORS_SCHEMA并查看它可能由于某些错误而未呈现(因为您说 html 的一部分不存在)。
推荐阅读
- css - Flex-grow 在 Angular 中不起作用
- dart - Dart:如何获取列表中的倒数第二个项目
- c - C中scanf()中的格式化字符串
- python - 'dict' 对象没有属性 'capitalize'
- javascript - 从 Google Functions 访问 Firestore - 从插件获取元数据失败并出现错误:无法刷新访问令牌
- android - Android:对话框不弹出
- cassandra - 提交日志刷新到 cassandra 中的 SSTable
- python - 我有一个文件位置存储在一个到达文件中。像\到达。它认为这是一个回车
- python - 根据numpy数组中的函数查找计数
- java - java - 如何穿越由java中的道路连接的城市网络?