Как установить значение NgForm в Observable и проверить, что оно было установлено? - PullRequest
0 голосов
/ 06 января 2019

Я пытаюсь проверить NgForm и проверить, установлено ли значение формы при обновлении состояния магазина.

@ViewChild('form') form: NgForm;

ngOnInit() {
this.subscription = this.store.select('shoppingList').subscribe(data => {
    this.editedItem = data.editedIngredient;
    this.form.setValue({ 
      name: this.editedItem.name,
      amount: this.editedItem.amount
    })
});

}

Но при установке значения я получаю

There are no form controls registered with this group yet.  
If you're using ngModel, you may want to check next tick (e.g. use setTimeout).

Также попытался создать поддельную форму и установить ее вместо NgForm

TestBed.createComponent(ShoppingEditComponent).debugElement.componentInstance.form = { value: {}, setValue: (newValue) => { this.value = newValue }};

но в тесте это значение никогда не обновляется, получая пустой value объект.

Каков наилучший подход к тестированию такого случая?

1 Ответ

0 голосов
/ 06 января 2019

@ ViewChild ('form') форма: NgForm;

будет недоступно в хуке жизненного цикла ngOnInit.

Сначала вам нужно создать форму, либо в конструкторе, либо в ngOnInit.

И только тогда вы можете выполнять методы в существующей форме.

Пример

export class MyComponent {
  form: FormGroup;
  editedItem;

  constructor(
    private formBuilder: FormBuilder
  ) {}

  ngOnInit() {
    this.createForm();
    this.subscribeToShoppingList();
  }

  private createForm() {
    this.form = this.formBuilder.group({
      name: null,
      amount: null
    });
  }

  private subscribeToShoppingList() {
    this.store.select('shoppingList').subscribe(data => {
      this.editedItem = data.editedIngredient;
      this.form.setValue({ 
        name: this.editedItem.name,
        amount: this.editedItem.amount
      });
    });
  }
}

В этом случае вам не нужно проверять то, что возвращает вам Store, вам будет достаточно для юнит-тестирования что-то вроде:

const mocks = {
  store: {
    select: sinon.stub().withArgs('shoppingList').returns(new Subject())
  }
};

let component: MyComponent;

describe('MyComponent', () => {
  beforeEach(() => {
    component = new MyComponent(
      new FormBuilder(),
      <any> mocks.store
    );
  });

  describe('ngOnInit', () => {
    beforeEach(() => {
      component.ngOnInit();
    });

    it('should create form', () => {
      expect(component.form).to.be.instanceof(FormGroup);
    });

    it('should create form with correct fields', () => {
      expect(component.form.value).to.haveOwnProperty('name');
      expect(component.form.value).to.haveOwnProperty('amount');
    });

    it('should subscribe to store.shoppingList', () => {
      expect(component.store.select).to.be.calledOnce.and.calledWith('shoppingList');
    });

    it('should set correct data from store to component', () => {
      component.store.select.next({
        editedIngredient: {
          name: 'new',
          amount: 100
        }
      });

      expect(component.editedItem.amount.to.eql(100));

      expect(component.form.value.name).to.eql('new');
    });

  });
});

Я не тестировал код, у него могут быть проблемы, но я надеюсь, что объяснил основную идею.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...