当前位置: 首页 > 知识库问答 >
问题:

具有双向绑定的 Angular 4 单元测试表单。从视图更新模型时出现问题

西门京
2023-03-14

我偶然发现了一个奇怪的问题。我正在使用基于模板的表单和双向绑定执行单元测试。以下是测试代码:

describe('Template Forms Input', () => {

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [BrowserModule, FormsModule],
      declarations: [DummyFormsComponent],
    }).compileComponents();
  });

  it('DOM input value changes the component model', fakeAsync(() => {

    const fixture = TestBed.createComponent(DummyFormsComponent);
    fixture.detectChanges();
    const dummyInputDe = fixture.debugElement.query(By.css('input'));
    const dummyInputEl = dummyInputDe.nativeElement;

    dummyInputEl.value = 'Super dummy';
    dummyInputEl.dispatchEvent(new Event('input'));

    tick();
    fixture.detectChanges();

    expect(fixture.debugElement.query(By.css('h2')).nativeElement.textContent).toEqual('Super dummy');
  }));
});

@Component({
  selector: 'dummy-forms',
  template: `
    <form>
      <input name="title" [(ngModel)]="model.anotherDummyValue">
    </form>
    <h2>{{model.anotherDummyValue}}</h2>
  `
})
class DummyFormsComponent {

  model = { anotherDummyValue: '', date: '' };
}

我无法通过测试。h2总是空的。然而。如果我删除<代码>

我认为我对异步行为做了一些错误的事情。有人有什么想法吗?

共有2个答案

柳刚豪
2023-03-14

尝试在代码中添加组件实例。更多 我在您的组件中看不到 ngOnInit 或构造函数。

组件=fixture.component实例;

我们通常以以下方式进行

describe('EditComponent', () => {
  let component: EditComponent;
  let fixture: ComponentFixture<EditComponent>;
  let displayText: DebugElement;
  let editableText: DebugElement;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        FormsModule,
        ReactiveFormsModule
      ],
      declarations: [ EditComponent, MockCkeditorComponent ]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(EditComponent);
    component = fixture.componentInstance;
    component.text = 'test input in the editor';
    displayText = fixture.debugElement.query(By.css('.row'));
    editableText = fixture.debugElement.query(By.css('.editor-form'));
  });

  it('should be created', () => {
    component.ngOnInit();
    fixture.detectChanges();
    expect(component).toBeTruthy();
  });
....

在beforeEach中声明您的组件。

涂泰平
2023-03-14

面对与您类似的问题(请参阅下面的Angular环境详细信息),搜索了所有关于单元测试的InternetNgModel。最后,我发现仅将值设置为查询的输入(实际上是通过NgModel绑定的)是不够的。即dummyInputEl.value='超级假人';调度事件('输入')在您的情况下永远不会启动并运行实际的NgModel操作。

为了解决这个问题,您必须从绑定的输入中获取注入的NgModel实例,并通过写值方法通过其值访问器属性设置值,然后在DOM本机元素上发出'输入'事件。

...
const ngModel = dummyInputDe.injector.get(NgModel);

tick();                    // <== Important to wait until stable before writing value

ngModel.valueAccessor.writeValue('Super dummy');
dummyInputDe.nativeElement.dispatchEvent(new Event('input'));

fixture.detectChanges();                   // <= force updates to the view


expect(fixture.debugElement.query(By.css('h2'))
  .nativeElement.textContent).toEqual('Super dummy');                // <= Viola!
...

请注意,在写入 NgModel 值访问器之前,我们必须在 fakeAsync 中提供刻度。可能是因为 NgModel 的访问器需要一部分时间来准备,然后才能在其上写入值(在这方面感谢反馈)。

而在没有fakeAsync区域的规范的情况下,应该使用fixture.whenStable()解析的promise来处理相同的场景以获得所需的结果。

注意:关于Web上单元测试的每个主题,尤其是当NgModel有问题时,这在任何地方都没有被提及。甚至官方的Angular留档也没有。不确定新的Angular版本(尤其是FormsMoules实现中的更改)是否强制进行了此更改。

    < Li > Angular < code > v 5 . 2 . 0 < Li > Karma < code > v 2 . 0 . 0 < Li > Jasmine(Jasmine-core)< code > v 2 . 8 . 0
 类似资料:
  • 我正在尝试测试Angular 2中的双向绑定功能。我还阅读了一些其他答案,但我仍然无法通过测试。 更新输入字段时,我想运行一个测试,以确保 AppComponent 类上的 searchQuery 属性与输入字段的值相同。 如前所述,我已经阅读了其他一些答案,并且随着我的学习,还包括了其他代码段。那么目前可能不需要的是什么? 成分 单元测试 如果有更好的方法,我当然很乐意得到任何反馈。

  • 本文向大家介绍VUE实现表单元素双向绑定(总结),包括了VUE实现表单元素双向绑定(总结)的使用技巧和注意事项,需要的朋友参考一下 本文介绍了VUE实现表单元素双向绑定(总结) ,分享给大家,具体如下: checkbox最基本用法: 规则1:如果v-model绑定的变量类型为boolean,若input被选中,this.inputdata为true,否则this.inputdata为false。

  • 在Spring Boot(Spring MVC)中,我试图根据本问题中的#4测试表单到控制器的绑定。我在复制魔法帖请求时遇到问题- 然而,我的断言失败了,itemModel。getId()返回null。当spring调用@Controller类上的方法时,我如何像spring那样初始化模型? 更新 我已经更新了以下内容,但它仍然不起作用:

  • 我面临一个问题,而嘲笑jUnit测试的东西。 情况如下: 类A实现了来自第三方jar的接口,并且需要实现method1。除了method1之外,A还包含method2,它是从method1调用的。method2本身调用一些外部服务。 我想单元测试方法1。 方法1接受输入,比如X。X有一个包裹在里面的输入变量,比如var1。var1由方法1中的逻辑使用,方法1在X中设置另一个变量,比如var2。 所

  • 本文向大家介绍浅谈mvvm-simple双向绑定简单实现,包括了浅谈mvvm-simple双向绑定简单实现的使用技巧和注意事项,需要的朋友参考一下 mvvm模式解放DOM枷锁 mvvm原理分析 JavaScript在浏览器中操作HTML经历了几个不同阶段 第一阶段 直接用浏览器提供的原生API操作DOM元素 第二阶段 jQuery的出现解决了原生API的复杂性和浏览器间的兼容性等问题,提供了更加简

  • 我希望我的swift代码在每次按下按钮时都添加一个新的tableview单元格。你可以在下面的gif中看到我想要的东西。这段代码应该在func-tableView(_tableView:UITableView,cellForRowAt-indexPath:indexPath)中添加按钮- 在此输入图像描述