Использование [(ngModel)] не применяет изменения в модульном тесте для входных данных внутри ngFor. - PullRequest
0 голосов
/ 07 декабря 2018

У меня проблемы с тестированием углового компонента, который использует двустороннюю привязку [(ngModel)] на входах флажков внутри ngFor.Это работает просто отлично в реальном приложении.Это просто проблема с тестом.

Вот пример теста, который не проходит:

import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { Component, EventEmitter, Output } from '@angular/core';
import { FormsModule } from '@angular/forms';

describe('Example Test', () => {
  @Component({
    template: `
      <input *ngFor="let value of values"
             type="checkbox"
             class="checkbox-1"
             [(ngModel)]="value.isSelected"
             (change)="output.emit(values)">
    `,
    styles: [``]
  })
  class TestHostComponent {
    @Output() output: EventEmitter<any> = new EventEmitter();

    values = [
      { isSelected: true },
      { isSelected: true },
      { isSelected: true },
    ];
  }

  let testHost: TestHostComponent;
  let fixture: ComponentFixture<TestHostComponent>;

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

  beforeEach(() => {
    fixture = TestBed.createComponent(TestHostComponent);
    testHost = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should change isSelected', fakeAsync(() => {
    const spy = spyOn(testHost.output, 'emit');
    fixture.nativeElement.querySelectorAll('.checkbox-1')[0].click();
    fixture.detectChanges();
    tick();

    expect(spy).toHaveBeenCalledWith([
      { isSelected: false }, // it fails because this is still true
      { isSelected: true },
      { isSelected: true },
    ]);
  }));
});

Использование [(ngModel)] с одним входом, который не находится в цикле, прекрасно работает в аналогичном тесте,Я даже зарегистрировал испущенное значение от (ngModelChange), и когда флажок установлен, $event равен true, когда оно действительно должно быть false.

Есть идеи?

1 Ответ

0 голосов
/ 09 декабря 2018

Похоже, что метод выполнения щелчка не вызывает обнаружение изменений.Отправка события изменения на флажок вместо этого дала ожидаемый результат:

it('should change isSelected', fakeAsync(() => {
    const spy = spyOn(testHost.output, 'emit');
    const checkbox = fixture.nativeElement.querySelectorAll('.checkbox-1')[0];
    checkbox.dispatchEvent(new Event('change'));
    fixture.detectChanges();
    tick();

    expect(spy).toHaveBeenCalledWith([
        { isSelected: false }, // This is now false
        { isSelected: true },
        { isSelected: true },
    ]);
}));

Решение, вдохновленное этим сообщением .

ОБНОВЛЕНИЕ:

Похоже, что нужно дождаться инициализации или регистрации некоторых элементов управления в CheckboxControlValueAccessor.Если вы измените второй beforeEach() для ожидания одного цикла после создания компонента, оригинальный код теста сработает:

beforeEach(fakeAsync(() => {
    fixture = TestBed.createComponent(TestHostComponent);
    testHost = fixture.componentInstance;
    fixture.detectChanges();
    tick();
}));

См. этот выпуск Github для полного ответа / объяснения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...