【问题标题】:Angular unit test input value角度单元测试输入值
【发布时间】:2017-04-25 02:02:13
【问题描述】:

我一直在阅读用于单元测试的官方 Angular2 文档 (https://angular.io/docs/ts/latest/guide/testing.html),但我正在努力设置组件的输入字段值,以便它反映在组件属性中(通过 ngModel 绑定)。屏幕在浏览器中工作正常,但在单元测试中我似乎无法设置字段值。

我正在使用以下代码。 “夹具”已正确初始化,因为其他测试工作正常。 “comp”是我的组件的实例,输入字段通过ngModel绑定到“user.username”。

it('should update model...', async(() => {
    let field: HTMLInputElement = fixture.debugElement.query(By.css('#user')).nativeElement;
    field.value = 'someValue'
    field.dispatchEvent(new Event('input'));
    fixture.detectChanges();

    expect(field.textContent).toBe('someValue');
    expect(comp.user.username).toBe('someValue');
  }));

我的 Angular2 版本:"@angular/core": "2.0.0"

【问题讨论】:

    标签: angular unit-testing angular2-testing


    【解决方案1】:

    输入没有文本内容,只有一个值。所以expect(field.textContent).toBe('someValue'); 没用。这可能就是失败的原因。不过,第二个期望应该会过去。这是一个完整的测试。

    @Component({
      template: `<input type="text" [(ngModel)]="user.username"/>`
    })
    class TestComponent {
      user = { username: 'peeskillet' };
    }
    
    describe('component: TestComponent', () => {
      beforeEach(() => {
        TestBed.configureTestingModule({
          imports: [FormsModule],
          declarations: [ TestComponent ]
        });
      });
    
      it('should be ok', async(() => {
        let fixture = TestBed.createComponent(TestComponent);
        fixture.detectChanges();
        fixture.whenStable().then(() => {
          let input = fixture.debugElement.query(By.css('input'));
          let el = input.nativeElement;
    
          expect(el.value).toBe('peeskillet');
    
          el.value = 'someValue';
          el.dispatchEvent(new Event('input'));
    
          expect(fixture.componentInstance.user.username).toBe('someValue');
        });
      }));
    });
    

    重要的部分是第一个fixture.whenStable()。发生的表单有一些异步设置,因此我们需要在执行fixture.detectChanges() 之后等待它完成。如果您使用fakeAsync() 而不是async(),那么您只需在fixture.detectChanges() 之后调用tick()

    【讨论】:

    • 即使没有第一个“期望”,我的也无法正常工作。但谢天谢地,你的工作正常,不知道为什么,我认为是因为它在 whenStable() 解决之后?无论如何感谢您的帮助。
    • 如果您在 beforeEach 中设置组件,使 beforeEach 异步,然后在创建组件后调用 fixture.detectChanges,可能会使用上面的代码而无需调用 whenStable。如果您使用上面的代码执行此操作,则可以摆脱除 then 回调中的所有内容之外的所有内容。我认为这也行得通。 async beforeEach 应该与 whenStable 做的事情几乎相同,即在退出 beforeEach 之前等待异步任务完成
    • fixture.whenStable().then(() =&gt; { - 谢谢。
    • ...peeskillet?
    • @JacobStamm 是吗?在我将其更改为真实姓名之前,那是我的 SO 用户名。
    【解决方案2】:

    只需添加

    fixture.detectChanges();
    
    fixture.whenStable().then(() => {
      // here your expectation
    })
    

    【讨论】:

    • 在每次测试中始终使用fixture.whenStable() 是否公平?像菜鸟一样,这是一个好主意还是仅在某些情况下使用?
    【解决方案3】:

    whenStable.then 函数中使用你的期望/断言,如下所示:

    component.label = 'blah';
    fixture.detectChanges();
    
    fixture.whenStable().then(() => {
        expect(component.label).toBe('blah');
    }
    

    【讨论】:

      【解决方案4】:

      如果您想使用 @Input 内容实现单元测试,请查看以下代码。

      testing.component.ts `

      import { Component, OnInit } from '@angular/core';
      @Component({
        selector: 'app-testing',
        templateUrl: `<app-input [message]='text'></app-input>`,
        styleUrls: ['./testing.component.css']
      })
      export class TestingComponent implements OnInit {
      public text = 'input message';
        constructor() { }
      
        ngOnInit() {
        }
      
      }
      

      `

      input.component.ts `

      import { Component, OnInit, Input } from '@angular/core';
      
      @Component({
        selector: 'app-input',
        templateUrl: `<div *ngIf="message">{{message}}</div>`,
        styleUrls: ['./input.component.css']
      })
      export class InputComponent implements OnInit {
      @Input() public message: string;
        constructor() { }
      
        ngOnInit() {
          console.log(this.message);
        }
      
      }
      

      `

      input.component.spec.ts

      `

      import { async, ComponentFixture, TestBed } from '@angular/core/testing';
      
      import { InputComponent } from './input.component';
      import { TestingComponent } from '../testing/testing.component';
      
      describe('InputComponent', () => {
        let component: InputComponent;
        let fixture: ComponentFixture<InputComponent>;
      
        beforeEach(async(() => {
          TestBed.configureTestingModule({
            declarations: [ InputComponent, TestingComponent ]
          })
          .compileComponents();
        }));
      
        beforeEach(() => {
          fixture = TestBed.createComponent(InputComponent);
          component = fixture.componentInstance;
          fixture.detectChanges();
        });
      
        it('should create', () => {
          expect(component).toBeTruthy();
        });
      
        it('should correctly render the passed @Input value', () => {
          component.message = 'test input';
          fixture.detectChanges();
          expect(fixture.nativeElement.innerText).toBe('test input');
        });
      
      });
      

      `

      【讨论】:

        猜你喜欢
        • 2022-01-03
        • 1970-01-01
        • 1970-01-01
        • 2022-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-10
        • 1970-01-01
        相关资源
        最近更新 更多