Форма отправляется без данных в модульном тестировании

#angular #jasmine #angular-material #karma-jasmine

#angular #jasmine #angular-материал #карма-жасмин

Вопрос:

У меня есть форма, которая использует компоненты из материала Angular. Я хочу проверить, что форма отправляется с ожидаемыми данными. Я опубликую упрощенную версию моего кода ниже, но в основном мой тест изменяет значение входных данных и имитирует нажатие на кнопку отправки. Я смог подтвердить, что входное значение действительно изменилось и форма отправлена, но проблема в том, что в нем говорится, что оно отправлено с пустым объектом, хотя мое утверждение подтвердило, что входное значение изменилось. Почему он распознает, что входное значение изменилось, но отправляет форму так, как будто этого не произошло? Я новичок в тестировании приложений Angular и потратил пару дней, пытаясь разобраться в этом, но безуспешно. Любая помощь была бы оценена.

Вот версии некоторых из моих модулей узла:

  • angular 7.2.8
  • материал 7.3.3
  • карма 4.0.1
  • jasmine-ядро 3.3.0
  • karma-jasmine 2.0.1

component.ts:

 export class FormComponent {
  @Input() loading: boolean;
  @Output() update: EventEmitter<Office> = new EventEmitter<Office>();

  saveForm(form: any) {
    const { value, valid } = form;

    if (valid) {
        this.update.emit(value);
    }
  }
}
  

component.html:

 <form *ngIf="!loading" (ngSubmit)="saveForm(form)" #form="ngForm" novalidate>
  <mat-form-field>
    <input
      class="company-name"
      matInput 
      placeholder="Company Name" 
      type="text"
      name="companyName"
      required
      #companyName="ngModel"
      [ngModel]="office?.companyName">
    <mat-error *ngIf="companyName.errors?.required amp;amp; companyName.dirty">
      Company name is required
    </mat-error>
  </mat-form-field>
 <button
    class="submit-form"
    mat-raised-button 
    type="submit"
    [disabled]="form.invalid"
  >
    Submit
  </button>
</form>
  

component.spec.ts:

 describe('FormComponent', () => {
  let component: FormComponent;
  let fixture: ComponentFixture<FormComponent>;
  let el: DebugElement;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        BrowserAnimationsModule,
        FormsModule,
        MatInputModule,
        OverlayModule,
        StoreModule.forRoot({}),
      ],
      declarations: [FormComponent],
      providers: [Actions, MatSnackBar, Store],
    }).compileComponents();
  }));

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

  it('should submit form when submit button is clicked', () => {
    // Setting input value
    el.query(By.css('input.company-name')).nativeElement.value = 'Test Name';
    fixture.detectChanges();
    // Confirming input value changed
    expect(el.query(By.css('input.company-name')).nativeElement.value).toBe(
      'Test Name',
    );
    // Spying on update method
    spyOn(component.update, 'emit').and.callThrough();
    el.query(By.css('button.submit-form')).nativeElement.click();
    // el.query(By.css('button.submit-form')).triggerEventHandler('click', null);
    expect(component.saveForm).toHaveBeenCalled();
    expect(component.update.emit).toHaveBeenCalledWith({ companyName: 'Test Name' });
  }):
});
  

Сообщение об ошибке:

Ожидалось, что spy emit был вызван с помощью [ Object({ CompanyName: ‘Имя теста’ }) ], но фактические вызовы были [ Object({ }) ].

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

1. Можете ли вы попробовать изменить свой spy и test на: const spy = spyOn(component.update, 'emit').and.callThrough(); expect(spy).toHaveBeenCalledWith({ companyName: 'Test Name' }); ?

2. Я попробовал это, и он все еще вызывается с пустым объектом