Angular 如何测试输入元素的类型?

Angular 如何测试输入元素的类型?,angular,typescript,unit-testing,testing,jasmine,Angular,Typescript,Unit Testing,Testing,Jasmine,我正在尝试测试输入元素的“键入”。我的目标是在输入元素中放入一些值,并查看其绑定是否具有输入的值,以及查看我在输入元素中输入的值 守则: 应用程序组件: import { Component } from "@angular/core"; @Component({ selector: "my-app", template: ` <span>My input: </span> <input name=&

我正在尝试测试输入元素的“键入”。我的目标是在输入元素中放入一些值,并查看其绑定是否具有输入的值,以及查看我在输入元素中输入的值

守则:

应用程序组件:

import { Component } from "@angular/core";

@Component({
  selector: "my-app",
  template: `
    <span>My input: </span>
    <input name="name-input" placeholder="Enter name" [(ngModel)]="name" />
  `,
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  name = "";
}

行后:

inputElement.value = "someValue";
inputElement.dispatchEvent(new Event("input"));
fixture.detectChanges();
预期:app.name等于“someValue”。 找到:app.name等于空字符串:“”

证明它不起作用的stackblitz: ?

您应该在区域内的上调度

然后,您的单元测试将如下所示:

it('#keydown should update app#name', fakeAsync(() => {

  // given
  let inputElement = fixture.nativeElement.querySelector(`input[name='name-input']`);
  
  // when
  let event = new KeyboardEvent('keydown', { key: 'x' });
  inputElement.dispatchEvent(event);
  tick();

  // then
  expect(app.name).toBe("x");
}));

我相信您需要的是以下代码:

it("should type text into input element after the view has been done initializing", () => {
  fixture.detectChanges(); // ngOnInit Lifecycle hook is run here

  let inputElement = fixture.nativeElement.querySelector(
    `input[name='name-input']`
  );

  inputElement.value = "someValue";
  inputElement.dispatchEvent(new Event("input"));

  fixture.detectChanges();
  expect(app.name).toBe("someValue");
});
现在,为什么这样做? 根据,当您第一次运行
fixture.detectChanges()
时,将调用
ngOnInit()
生命周期挂钩,这是导致错误的关键

您正在
ngOnInit()
之外设置值,但是初始化视图的生命周期挂钩尚未运行。这意味着当您第一次调用
ngOnInit()
lifecycle钩子时调用
fixture.detectChanges()
。然后,这会将视图重新初始化为其原始状态,从而恢复以前所做的所有更改(如设置输入值)


问候。

我将您的代码复制到stackblitz(我用您的代码更新了它),但它仍然不起作用。它有以下错误:“TypeError:无法读取未定义的属性'assertPresent'”,那么会发生什么?错误?测试失败?设置值,然后触发输入事件per,仍然可以正常工作,例如@jonrsharpe测试失败,预期为“someValue”,发现为:“”。现在,我将您的解决方案添加到stackblitz(我更新了它)。你可以看到测试失败了。在问题中加上a,异地链接应该是补充的。@jornsharpe,但这已经是“可复制的例子”。我在我的电脑上测试过它=>不起作用。所以我分享了一个stackblitz来证明它不起作用,并且所有的测试都失败了。同时用你的和uminder的解决方案更新stackblitz,以证明它。“描述问题。”它不起作用“描述不足以帮助人们理解您的问题。相反,告诉其他读者预期的行为应该是什么。告诉其他读者错误消息的确切措辞,以及产生错误消息的代码行。用一个简短但描述性的问题摘要作为你问题的标题。“非常感谢!很有效!但我还有一个问题要问。它通过了测试=>很好!但是如果你在应用程序中进行测试,为什么我看不到“somevalue”在测试完成时出现在输入元素中?(假设这是唯一一个正在运行的测试)(在StkBLITTZ上)你可以在测试中放置Byebug。你会看到输入字段被创建,填充了文本,然后在测试结束时重置。实际上,我们看不到文本,因为文本运行得太快,以至于我们无法看到/浏览器考虑渲染。
it("should type text into input element after the view has been done initializing", () => {
  fixture.detectChanges(); // ngOnInit Lifecycle hook is run here

  let inputElement = fixture.nativeElement.querySelector(
    `input[name='name-input']`
  );

  inputElement.value = "someValue";
  inputElement.dispatchEvent(new Event("input"));

  fixture.detectChanges();
  expect(app.name).toBe("someValue");
});