我有一个Angular2组件,其中包含一个如下所示的选择框
<select [(ngModel)]="envFilter" class="form-control" name="envSelector" (ngModelChange)="onChangeFilter($event)">
<option *ngFor="let env of envs" [ngValue]="env">{{env}}</option>
</select>
我正在尝试为ngModelChange事件编写单元测试。这是我最近一次失败的尝试
it("should filter and show correct items", async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
el = fixture.debugElement.query(By.name("envSelector"));
fixture.detectChanges();
makeResponse([hist2, longhist]);
comp.envFilter = 'env3';
el.triggerEventHandler('change', {});
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(comp.displayedHistory).toEqual(longhist);
});
});
我遇到的问题是,更改底层模型comp.envFilter = 'env3';
的值不会触发change方法。我添加了el.triggerEventHandler('change', {});
,但这会抛出Failed: Uncaught (in promise): ReferenceError: By is not defined
。我在文档中找不到任何提示......有什么想法吗?
4条答案
按热度按时间7kqas0il1#
就错误而言。看起来你只需要导入
By
。这不是全局的东西。它应该从下面的模块导入至于测试部分,这是我已经能够弄清楚的。当你改变组件中的一个值时,你需要触发一个变化检测来更新视图。你可以用
fixture.detectChanges()
来做这件事。一旦完成了这件事,* 通常 * 视图应该用这个值来更新。通过测试类似于您的示例的东西,似乎情况并非如此。似乎在变更检测之后仍有一些异步任务在进行。
这似乎不起作用。似乎有一些异步正在进行,导致值还没有设置。所以我们需要通过调用
fixture.whenStable
等待异步任务上面的方法是可行的,但是现在我们需要触发change事件,因为它不会自动发生。
现在我们有了另一个来自事件的异步任务。
下面是我测试的一个完整的测试。它是对source code integration tests示例的重构。他们使用了
fakeAsync
和tick
,这与使用async
和whenStable
类似。但是对于fakeAsync
,你不能使用templateUrl
,所以我认为最好重构为使用async
。源代码测试也做了双重单向测试,首先测试模型到视图,然后测试视图到模型。虽然看起来你的测试是尝试做一种双向测试,从模型到模型。所以我重构了一点,以更好地适合你的例子。
wsewodh22#
我发现peeskillet的答案非常有用,但遗憾的是,它有点过时了,因为调度事件的方式已经改变了。我还发现有一个不必要的调用whenStable()。所以这里是一个使用peeskillet的设置更新的测试:
disho6za3#
看这个例子,来自Angular 源(template_integration_spec.ts)
svujldwt4#
与OP提出的问题相同,但代码略有不同。
适用于Angular 7。
于飞:
单元测试: