Угловое тестирование: значение FormControlChanges Observable

У меня есть ввод текста, и я прислушиваюсь к изменениям.

компонент

name = new FormControl('',Validators.required);

ngOnInit() {
  this.data = 'oldvalue';
  this.checkName();
}

checkName() {
  this.name.valueChanges.subscribe(val=>{
     console.info(val);
     this.data= "newvalue"; // updating Value
  });
}

HTML

<input name = "name" formControlName = "name">

Моя попытка до сих пор:

component.spec.ts

it('should test data field ', () => {
    const fixture = TestBed.createComponent(UserComponent);
    const app=fixture.debugElement.componentInstance;
    const el = fixture.nativeElement.querySelector('input');
    el.value ='something';
    dispatchEvent(new Event(el));
    fixture.detectChanges();
    fixture.whenStable().then(()=>{expect(app.data).toBe('newvalue');
});

Проблема: Несмотря на то, что поле ввода заполнено, код внутри обратного вызова подписки никогда не выполняется.

Всегда показывает:

Expected 'oldvalue' to be 'newvalue'.

Я тоже попробовал метод setValue(), но он не сработал. он никогда не попадает в обратный вызов подписки

app.name.setValue('vikas');
fixture.detectChanges();
fixture.whenStable().then(()=>{expect(app.data).toBe('newvalue');

Я сослался на Обновление поля ввода html из теста Angular 2 и Компонент Angular2: изменение входного значения формы тестирования, но не повезло :(

Что мне не хватает?

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
16
0
20 078
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На первый взгляд мне кажется, вы упустили тот факт, что ваш FormControl не подключен к вводу, потому что вы используете директиву FormControlName, которая принимает имя элемента управления как @Input.

Если вы хотите протестировать FormControl, вы можете рассмотреть FormControlDirective, который принимает FormControl как @Input:

<input name = "name" [formControl] = "name">
                                  ^^^^^
                      `name` is FormControl instance here not string

Теперь мы можем быть уверены, что всякий раз, когда мы меняем текст во вводе, ваш FormControl запускает изменения. Но как только вы напишете такой шаблон, angular спросит у вас зависимость ReactiveFormsModule в вашем тесте:

import { ReactiveFormsModule } from '@angular/forms';
....

TestBed.configureTestingModule({
   imports: [
     ReactiveFormsModule  <=== add this
   ],
   declarations: [TestComponent],
});

Теперь по поводу вашего теста.

1) Вы должны указать TestBed выполнить привязку данных, вызвав fixture.detectChanges():

const fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges(); <== add this

2) Вы должны правильно запустить изменение при вводе:

el.dispatchEvent(new Event('input'));

Вот весь код:

it('should display original title', () => {
  const fixture = TestBed.createComponent(TestComponent);
  fixture.detectChanges();
  const app = fixture.debugElement.componentInstance;
  const el = fixture.nativeElement.querySelector('input');
  el.value = 'something';
  el.dispatchEvent(new Event('input'));
  fixture.detectChanges();
  fixture.whenStable().then(() => {
    expect(app.data).toBe('newvalue');
  });
});

Пример Plunker

Thanx Mate Работал как шарм :)

Vikas 18.08.2018 19:44

Привет, у меня проблема с этим подходом, пожалуйста, видите ли вы этот вопрос stackoverflow.com/questions/58355726/…

user5155835 12.10.2019 17:38

Я использую последнюю версию Angular и Jest, мне пришлось дождаться fixture.whenStable (), затем выполнить assert

pcdro 18.12.2019 21:23

Большое спасибо, это действительно помогло.

priyanka 05.10.2020 22:46

Другие вопросы по теме