Протестируйте поле реактивной формы, имеющее пользовательский валидатор в Angular

#javascript #angular #unit-testing #testing

#javascript #angular #модульное тестирование #тестирование

Вопрос:

Я пытаюсь проверить допустимое состояние пользовательского проверяемого поля в реактивной форме.

Мой компонент выглядит следующим образом:

 import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { ageRangeValidator } from './age-range-validator.directive';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Reactive Forms';
  genders = ['Female', 'Male'];

  constructor(private fb: FormBuilder) { }

  userForm = this.fb.group({
    firstname: ['', [Validators.required, Validators.minLength(2)]],
    surname: ['', [Validators.required, Validators.minLength(2)]],
    address: this.fb.group({
      houseNo: [''],
      street: [''],
      city: [''],
      postcode: ['']
    }),
    // Section 1
    // age: [null, Validators.min(18)],
    // Section 2 - using a Custom validator
    age: [null, ageRangeValidator(18, 68)],
    gender: ['']
  });
}  

Функция ageRangeValidator заключается в следующем — она была полностью протестирована и работает:

 import { AbstractControl, ValidatorFn } from '@angular/forms';

export function ageRangeValidator(min: number, max: number): ValidatorFn {
  return (control: AbstractControl): { [key: string]: boolean } | null => {
    if ((!isNaN(control.value) amp;amp; control.value) amp;amp; control.value > min amp;amp; control.value < max) {
      return { 'ageRange': true };
    }
    return null;
  };
}  

У меня есть тест для компонента приложения, настроенный, как показано ниже, где я устанавливаю значение поля age, а затем проверяю, действительно ли оно — тест возвращает значение validity равным false:

 import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { ReactiveFormsModule } from '@angular/forms';
import { DebugElement } from '@angular/core';

describe('AppComponent', () => {
  let fixture: ComponentFixture<AppComponent>;
  let app: AppComponent;


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

  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AppComponent);
    app = fixture.debugElement.componentInstance;
    fixture.detectChanges();
  });
  
  describe(`Test the validity of the fields`, () => {
    it(`should return true if a value of 18 or more AND 68 or LESS is supplied (as string or number)`, () => {
      const age = app.userForm.controls['age'];
      age.setValue(42);
      expect(age.valid).toBeTruthy();
    });
  });  

Я ожидаю, что для решения потребуется, чтобы функция ageRangeValidator каким-то образом была подключена к тестовому компоненту, но я не могу понять, как — кто-нибудь, пожалуйста, может предложить способ, которым я мог бы это сделать (если это вообще возможно)?

В конечном счете, я пытаюсь проверить действительность формы, чтобы убедиться, что ее можно отправить, когда все обязательные поля действительны.

Ответ №1:

  1. Используйте controls.get(‘age’), старайтесь избегать прямого доступа к элементам управления
  2. Вам нужно https://angular.io/api/core/testing/tick после установки значения запустите процесс проверки

Комментарии:

1. Спасибо за ваши предложения, я реализовал пункт 1! Не могли бы вы, пожалуйста, подробнее остановиться на пункте 2 — я пытался преобразовать спецификацию в fakeAsync и ввести tick(1000) , но я получаю ошибки. Я не уверен, что я точно понимаю, что вы имеете в виду?

2. tick() (то же, что tick(0)) должно быть достаточно, потому что проверка ожидает ближайшей возможности для выполнения микрозадачи. Не могли бы вы, пожалуйста, показать мне точные ошибки, которые оно показывает?

3. Еще раз, спасибо за reply…my исправленный пакет теперь доступен:

4. describe('Test the validity of the fields', () => { it('should return true if a value of 18 or more AND 68 or LESS is supplied (as string or number)', fakeAsync(() => { const age = app.userForm.get('age'); age.setValue(42); tick(); age.updateValueAndValidity(); tick(); expect(age.valid).toBeTruthy(); })); });

5. Chrome 72.0.3626 (Mac OS X 10.14.3): Выполнено 1 из 1 (1 СБОЙ) (0 секунд / 0,269 секунды) Chrome 72.0.3626 (Mac OS X 10.14.3) AppComponent Test проверка правильности полей должна возвращать значение true, если указано значение 18 или более и 68 или МЕНЕЕ (в виде строки или числа), НЕ УДАЛОСЬ Ожидаемое значение false соответствует действительности. в пользовательском тексте.<анонимный> src/app/app.component.spec.ts:79:31) в пользовательском тексте.<анонимный> node_modules/zone.js/dist/zone-testing.js:1429:1) в

Ответ №2:

Для всех, кто сталкивается с этим, если вы правильно написали свой пользовательский валидатор, вам не нужно делать ничего особенного. Если вы получаете ошибку ссылки, просто повторно сохраните свои файлы. Вам не нужно ничего особенного делать, чтобы подключить пользовательский валидатор в спецификации реактивной формы, вам даже не нужно импортировать его в файл спецификации.