0

I have a case where I use NgForm validation on an input[type="file].

The code works fine in a real case scenario (browser usage). However on the testing part itself I have a code that prevent the actual form data submission (including the file) if there is an error in the ngForm (by checking ngForm.valid).

The following test is considering that the ngForm.valid === false so the test fails:

it('should do a SubsectionSave save on submit and attach file', async () => {
      const dataTransfer = new DataTransfer();
      dataTransfer.items.add(await testGetExampleFile()); // testGetExampleFile returns a valid File object
      // set file and trigger event
      const inputDebugEl  = fixture.debugElement.query(By.css('input[type=file]'));
      inputDebugEl.nativeElement.files = dataTransfer.files;
      inputDebugEl.nativeElement.dispatchEvent(new InputEvent('change'));
      fixture.detectChanges();
      await fixture.whenStable();

      component.submit(); // this submit function checks the .valid on the ngForm, but does nothing

      // expect(a-backend-save-call).toBeDone();
      // but nothing is done because the submit() stops at the .valid checking
});

The way to put a file into the input from the test case itself was inspired by How to write the unit testing for the file upload method in the Angular 7 (or 2+)

I have checked the ngForm.controls before the ngForm.valid check (in the actual implementation) and there are multiple required fields but the only one to be marked as invalid (cause: required) is this required input-file.

Is there a way to force angular to detect the new presence of the new file?

I tried a mix of fixture.detectChanges();, waiting for 1sec after the change event being raised, await fixture.whenStable(); at several places after nativeElement files being set, but nothing worked.

How to deal with required input file within angular component tests ?

Micaël Félix
  • 2,697
  • 5
  • 34
  • 46

1 Answers1

1

I finally found the solution, based on triggerEventHandler of the DebugElement, as shown here:

      const file: File = await testGetExampleFile('pdf');

      // set file and trigger event
      const inputDebugEl  = fixture.debugElement.query(By.css('input[type=file]'));
      inputDebugEl.triggerEventHandler('change',  { target: { files: [file] } });
Micaël Félix
  • 2,697
  • 5
  • 34
  • 46