Не удается прочитать свойства неопределенного (чтение ‘value’) в тесте снапшота Jest

Вопрос или проблема

Я тестирую компонент в своем приложении Angular v15. Пока что только один тест не прошел, мой тест снимка:

describe('Снимок', () => {
    it('базовый', waitForAsync(() => {
      fixture.detectChanges();

      expect(fixture).toMatchSnapshot();
    }));
  });

Все остальные тесты проходят. Ошибка, которую я получаю, следующая:

TypeError: Невозможно прочитать свойства неопределенного (чтение 'value')

      в <ИмяКомпонента>_Шаблон (ng:/<ИмяКомпонента>.js:360:65)
      в executeTemplate (node_modules/@angular/core/fesm2020/core.mjs:10441:9)
      в refreshView (node_modules/@angular/core/fesm2020/core.mjs:10326:13)
      в refreshComponent (node_modules/@angular/core/fesm2020/core.mjs:11385:13)
      в refreshChildComponents (node_modules/@angular/core/fesm2020/core.mjs:10116:9)
      в refreshView (node_modules/@angular/core/fesm2020/core.mjs:10376:13)
      в detectChangesInternal (node_modules/@angular/core/fesm2020/core.mjs:11529:9)
      в RootViewRef.detectChanges (node_modules/@angular/core/fesm2020/core.mjs:12020:9)
      в ComponentFixture._tick (node_modules/@angular/core/fesm2020/testing.mjs:126:32)
      в node_modules/@angular/core/fesm2020/testing.mjs:139:22
      в _ZoneDelegate.Object.<анонимный>._ZoneDelegate.invoke (node_modules/zone.js/dist/zone-node.js:400:30)
      в AsyncTestZoneSpec.Object.<анонимный>.AsyncTestZoneSpec.onInvoke (node_modules/zone.js/dist/async-test.js:127:47)
      в ProxyZoneSpec.Object.<анонимный>.ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/proxy.js:123:43)
      в _ZoneDelegate.Object.<анонимный>._ZoneDelegate.invoke (node_modules/zone.js/dist/zone-node.js:399:56)
      в Object.onInvoke (node_modules/@angular/core/fesm2020/core.mjs:24210:33)
      в _ZoneDelegate.Object.<анонимный>._ZoneDelegate.invoke (node_modules/zone.js/dist/zone-node.js:399:56)
      в Zone.Object.<анонимный>.Zone.run (node_modules/zone.js/dist/zone-node.js:160:47)
      в NgZone.run (node_modules/@angular/core/fesm2020/core.mjs:24064:28)
      в ComponentFixture.detectChanges (node_modules/@angular/core/fesm2020/testing.mjs:138:25)
      в src/modules/action-template/media-type-form/<ИмяКомпонента>/<ИмяКомпонента>.component.spec.ts:685:15
      в _ZoneDelegate.Object.<анонимный>._ZoneDelegate.invoke (node_modules/zone.js/dist/zone-node.js:400:30)
      в AsyncTestZoneSpec.Object.<анонимный>.AsyncTestZoneSpec.onInvoke (node_modules/zone.js/dist/async-test.js:127:47)
      в ProxyZoneSpec.Object.<анонимный>.ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/proxy.js:123:43)
      в _ZoneDelegate.Object.<анонимный>._ZoneDelegate.invoke (node_modules/zone.js/dist/zone-node.js:399:56)
      в Zone.Object.<анонимный>.Zone.runGuarded (node_modules/zone.js/dist/zone-node.js:171:51)
      в runInTestZone (node_modules/zone.js/dist/async-test.js:272:33)
      в node_modules/zone.js/dist/async-test.js:223:21
      в новом ZoneAwarePromise (node_modules/zone.js/dist/zone-node.js:1270:25)
      в node_modules/zone.js/dist/async-test.js:222:24
      в _ZoneDelegate.Object.<анонимный>._ZoneDelegate.invoke (node_modules/zone.js/dist/zone-node.js:400:30)
      в ProxyZoneSpec.Object.<анонимный>.ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/proxy.js:126:43)
      в _ZoneDelegate.Object.<анонимный>._ZoneDelegate.invoke (node_modules/zone.js/dist/zone-node.js:399:56)
      в Zone.Object.<анонимный>.Zone.run (node_modules/zone.js/dist/zone-node.js:160:47)
      в Object.<анонимный> (node_modules/jest-zone-patch/index.js:50:27)

HTML использует formGroup, названный form, чтобы его можно было ссылаться как this.form.value.<formControlName>.

Поскольку журнал ошибок очень неинформативен, я не знаю, где искать решение. Страница работает прекрасно, ошибок нет. Только тесты не проходят.

Фрагмент HTML:

<CompanyCustomTextInput label-position="above">
   <label slot="label" for="title-input">{{'TITLE' | translate}}</label>
   <input
      slot="input"
      type="text"
      class="text-input"
      id="title-input"
      placeholder="{{'TITLE_PLACEHOLDER' | translate}}"
      formControlName="title"
      [maxlength]="maxLengthTitle"
   />
</CompanyCustomTextInput>

Есть еще более вводов разного и одинакового типа, но все они следуют этому шаблону.

Я пытался удалить все this.form.value из полей ввода, пытался изменить formControlName. Без успеха.

Ответ или решение

Ошибка "Cannot read properties of undefined (reading ‘value’)" во время выполнения теста snapshot в вашем приложении на Angular v15 может быть вызвана рядом факторов, связанных с конфигурацией ваших форм и их состоянием при запуске тестов. В этом ответе мы подробно рассмотрим возможные причины и решения данной проблемы.

1. Проверка инициализации FormGroup

Убедитесь, что ваш FormGroup корректно инициализирован до того, как вызывается fixture.detectChanges(). Часто эта ошибка возникает, если form не инициализирован и остается undefined, когда компоненты пытаются получить доступ к его свойствам.

Пример корректной инициализации FormGroup может выглядеть так:

import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { ComponentName } from './component-name.component';

describe('ComponentName', () => {
  let component: ComponentName;
  let fixture: ComponentFixture<ComponentName>;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      imports: [ReactiveFormsModule],
      declarations: [ComponentName]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ComponentName);
    component = fixture.componentInstance;
    component.form = new FormGroup({
      title: new FormControl('')
      // другие элементы формы
    });
    fixture.detectChanges();
  });

  it('basic', () => {
    expect(fixture).toMatchSnapshot();
  });
});

2. Актуализация значений формы

Перед выполнением теста убедитесь, что все значения для элементов вашей формы установлены:

component.form.get('title').setValue('Тестовое значение');

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

3. Проверка HTML-шаблона

Убедитесь, что правильно указан formControlName для каждого элемента в вашем HTML и что эти контроллеры существуют в FormGroup. В вашем HTML-коде:

<CompanyCustomTextInput label-position="above">
   <label slot="label" for="title-input">{{'TITLE' | translate}}</label>
   <input
      slot="input"
      type="text"
      class="text-input"
      id="title-input"
      placeholder="{{'TITLE_PLACEHOLDER' | translate}}"
      formControlName="title"
      [maxlength]="maxLengthTitle"
   />
</CompanyCustomTextInput>

Убедитесь, что formControlName="title" соответствует ключу в вашем FormGroup.

4. Взаимодействие с асинхронными действиями

Если ваша форма или её элементы зависят от каких-либо асинхронных действий (например, загрузка данных), может потребоваться использование fakeAsync и tick(), чтобы убедиться, что все асинхронные операции завершились до выполнения теста.

5. Отладка

В случае продолжения проблемы используйте инструменты отладки, такие как console.log(), чтобы вывести текущее состояние form и его контроллеров перед выполнением fixture.detectChanges():

console.log(this.form);

Это поможет вам увидеть, загружены ли данные потенциально неправильно, или у вас просто проблема с доступом к свойствам.

Заключение

Проблема "Cannot read properties of undefined (reading ‘value’)" может возникнуть по множеству причин, но основные шаги, которые следует предпринимать, включают в себя правильную инициализацию FormGroup, актуализацию значений формы и тщательную проверку HTML-шаблона. Применение вышеперечисленных рекомендаций должно помочь в устранении ошибки и успешном выполнении ваших snapshot-тестов. Если проблема сохраняется, рассмотрите возможность более глубокого анализа конфигурации вашего компонента и форм.

Оцените материал
Добавить комментарий

Капча загружается...