проверить значения в блоке подписки метода AuditTime модуля реактивной формы - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь проверить значения внутри блока .subscribe в модульном тесте жасмина angular4 / typescript, в котором используется метод rxjs auditTime.Я прочитал много похожих постов к этому, которые, кажется, не попадают в этот блок.

У меня есть следующий пример компонента:

address.component.ts:

export class AddressComponent implements OnInit {

  public form: FormGroup;

  constructor (
    private fb: FormBuilder
  ) {}

  public ngOnInit (): void {
    this.createForm();
  }

  public createForm (): void {
    this.form = this.fb.group({
      lineOne: [this.address.lineOne],
    });

    this.form.valueChanges.auditTime(500).subscribe(() => {
      this.address.lineOne = this.form.value.lineOne;
    });
  }
}

address.component.html:

<div class="address">
  <form [formGroup]="form">
    <div class="row">
      <div class="col-12 address-body">
        <div class="form-group-main">
          <div class="row">

            <div class="address-input col-12">
              <label for="address-line-one" [class.required]="isMandatory">Address Line 1</label>
              <input class="form-control" id="address-line-one" type="text" formControlName="lineOne">
            </div>

          </div>
        </div>
      </div>

      <div class="col-12 address-body">
        <display-address [body]="address.lineOne"></display-address>
      </div>

      <div class="col-12">
        <button class="btn btn-full-width btn-primary btn-sm btn-edit" id="address-edit" type="button" (click)="...">Edit</button>
      </div>

    </div>
  </form>
</div>

address.component.spec.ts:

describe('Address Component', () => {
  let component: AddressComponent;
  let fixture: ComponentFixture<AddressComponent>;

  beforeEach(async(() => {

    TestBed.configureTestingModule({
      declarations: [AddressComponent],
      imports: [ReactiveFormsModule],
      schemas: [NO_ERRORS_SCHEMA],
    }).compileComponents().then(() => {
      fixture = TestBed.createComponent(AddressComponent);
      component = fixture.componentInstance;
    });

  }));

  it('should update address', fakeAsync(() => {
    component.address = {lineOne: 'street'};
    fixture.detectChanges();

    //do something.. 

  }));

});

при условии, что все вышеперечисленное было настроено правильно, и я не пропустил что-то явно очевидное, поэтому мои тесты никогда не дают правильных результатов, я попытался изменить свой тест следующими идеями:

слежка за AuditTime и вызов:

spyOn(component.form.valueChanges,'auditTime').and.returnValue(Observable.of('hello'));

вызов его напрямую:

component.form.valueChanges.auditTime().subscribe(result => {
   //never get in here
});

попытка ожидания с использованием: tick() и попытка сброса с помощью: flushMicrotasks().

шпионаж в функции createForm:

spyOn(component, 'createForm').and.callFake(() => {
    return Observable.of('hello');
});

использование debugElement для доступа и обновления lineOne всегда возвращает ошибки, если я использую следующиеng:

const el = fixture.nativeElement.querySelector(By.css('#address-line-one'));
el.value = 'something';
el.dispatchEvent(new Event('input'));
fixture.detectChanges();

, как это может показаться, он может видеть только кнопку редактирования html и <display-address></display-address>, предполагая, что она может быть не скомпилирована в данный момент.

Я также пытался обернуть все в:

fixture.whenStable().then(() => {
    // do something.. 
});

, и теперь у меня нет идей, если кто-то сможет понять вышесказанное и направить меня в правильном направлении, этобыло бы здорово ..


РЕШЕНИЕ


Благодаря Амиру может показаться, что в этом конкретном примере я серьезно продумал ответы, необходимые для этого, и использовалNO_ERRORS_SCHEMA скрывал истинную проблему.Оказывается, мне нужно было импортировать компонент, который <display-address> требовался:

imports: [ReactiveFormsModule, DisplayAddressComponent],

, что позволило шаблону правильно скомпилироваться, то есть я мог видеть все значения формы вместо <display-address>.В соответствии с рекомендациями я использовал комбинацию fakeAsync и tick(600) для выдачи изменения в форму:

it('should update address', fakeAsync(() => {
    component.address = {lineOne: 'street'};
    fixture.detectChanges();

    expect(component.address.lineOne).toBe('street');
    component.form.controls['lineOne'].setValue('test');
    tick(600);

    expect(component.address.lineOne).toBe('test');
  }));

, только если у кого-то возникла подобная проблема.

1 Ответ

0 голосов
/ 02 февраля 2019

Хорошо, я просто опубликую здесь свои предположения, проверьте, поможет ли это:

  1. Вызовите ngOnInit () напрямую или используя detectChanges () сразу после вы создаете компонент ;
  2. Тест должен работать синхронно только при использовании fakeAsync + tick (600);
  3. После вы выполнили tick (600) , пытаясь передать значение в this.form.valueChanges , вы можете сделать это, подставив FormBuilder , поэтому он вернет объект с вашим собственным эмиттером (субъектом) или найдет элемент в html и , введя значение с событием DOM .
  4. Если вырешите использовать html для ввода , удалить NO_ERRORS_SCHEMA и посмотреть, может быть, он не отображается из-за некоторых ошибок (потому что вы сказали, что часть html не присутствовала).
...