Как проверить form.valueChanges в Angular? - PullRequest
0 голосов
/ 17 октября 2018

Как правильно выполнить юнит-тест (Карма, Жасмин), чтобы выбросы valueChanges отправляли действие FormUpdated?

beforeEach(async(() => {
  TestBed.configureTestingModule({
    imports: [...],
    providers: [
      { provide: Store, useValue: MOCK_STORE },
    ],
    declarations: [FormComponent],
    schemas: [NO_ERRORS_SCHEMA]
  })
    .compileComponents();
}));

beforeEach(() => {
    fixture = TestBed.createComponent(FormComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
});
export class FormComponent implements OnInit {
    searchForm: FormGroup;

    constructor(private readonly fb: FormBuilder, private readonly store: Store<AppState>) {
    }

    ngOnInit(): void {
        this.searchForm = this.fb.group({});
        this.searchForm.valueChanges.subscribe(value => this.store.dispatch(new FormUpdated(value)));
    }
}

Я пробовал что-то вроде этого:

it('should dispatch action for valueChanges', () => {
    const spy = spyOn(component['store'], 'dispatch');
    spyOn(component.searchForm, 'valueChanges').and.returnValue(of({}));

    expect(spy).toHaveBeenCalledTimes(1);
});

Но это не работает - шпион не был вызван.

[Edit1] - Основано на комментариях и ответе:

Проблема стест асинхронности.Некоторая часть ngOnInit вызывает setTimeout(() => this.searchForm.get('field').updateValueAndValidity();)), что приводит к потере this.searchForm.valueChanges(), поэтому this.store.dispatch фактически вызывается, но после expect(spy).toHaveBeenCalledTimes(1).

я пыталсядобавьте fakeAsync(), tick() и flushMicrotasks(), но с тем же результатом.

it('should dispatch action for valueChanges', () => {
    const spy = spyOn(component['store'], 'dispatch');
    spyOn(component.searchForm, 'valueChanges').and.returnValue(of({}));

    tick();
    flushMicrotasks();

    expect(spy).toHaveBeenCalledTimes(1);
});

1 Ответ

0 голосов
/ 18 октября 2018

Вы хотите проверить изменения в форме без ввода.Возможно попробуйте с этим:

this.searchForm = this.fb.group({description: ['your_input']});

.

beforeEach(async(() => {
  TestBed.configureTestingModule({
    imports: [...],
    providers: [
      { provide: Store, useValue: MOCK_STORE },
    ],
    declarations: [FormComponent],
    schemas: [NO_ERRORS_SCHEMA]
  })
    .compileComponents();
}));

beforeEach(() => {
    fixture = TestBed.createComponent(FormComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
});

it('should dispatch action for valueChanges', () => {
    const spy = spyOn(TestBed.get(Store<AppState>), 'dispatch') 
    component.searchForm.controls['your_input'].setValue('test') // This will trigger change
    expect(spy).toHaveBeenCalledTimes(1);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...