I have an input
HTML
File
filed
<input type="file" class="custom-file-input" id="question-file-upload" formControlName="image" (change)="handleFileSelect($event)">
I want to unit test handleFileSelect
function. But I don't know how to trigger the onChange
method of the input. Following is the spec
I have written but I get error imageInputNE.onchange is not a function
fit('should keep track of image counter when an image is loaded', () => {
let newPracticeQuestionComponent = component;
expect(newPracticeQuestionComponent.currentImageAttachmentCount).toBe(0);
let imageInputDE = fixture.debugElement.query(By.css("#question-file-upload"));
expect(imageInputDE).toBeTruthy();
spyOn(newPracticeQuestionComponent,'handleFileSelect');
let imageInputNE:HTMLElement = imageInputDE.nativeElement as HTMLElement;
imageInputNE.onchange(new Event("some event"));
expect(newPracticeQuestionComponent.handleFileSelect).toHaveBeenCalled();
});
Referring to documentation at Mozilla's website, Events are usually triggered by "external" sources like Buttons, they can also be triggered programmatically, such as by calling the HTMLElement.click() method of an element. or by defining the event, then sending it to a specified target using EventTarget.dispatchEvent().
I suppose that
click
is a simple Event and can be triggered programatically butchange
Event for<input type=file..>
is more complicated as it requires selecting a file, converting into a blog, updatingfiles
property etc. So probably for this reason, I cannot just simply callimageElementNE.change()
.So I thought of using
dispatchEvent
and it seem to work1) I created an Event explicitly. I suppose
Event
's constructor takes 2 arguments, 2nd is optional.From https://developer.mozilla.org/en-US/docs/Web/API/Event/Event
From documentation,
typeArg
is a DOMString representing the name of the event. In other words, the 1st argument seem to be thetype
of the event. As I want to sendchange
event, I need to call itchange
.For the
eventInit
part, I looked at the definition ofchange
event at https://developer.mozilla.org/en-US/docs/Web/Events/change and picked the values ofbubbles
andcancelable
from thereThis creates an
Event
which looks as follows (I must confess I don't understand much of it)2) Once the
Event
was created, I called thedispatchEvent
method onimageInputNE
. Comparing withEventTarget.dispatchEvent()
, I think it means that theEventTarget
is triggering the event (in my caseimageInputNE
is triggeringfileSelectEvent
.The entire spec which passed is
The above might not be the best solution as I can't manipuate
files
in theinput
field but this is the best I could come up with!Coming from the other answer, I'd suggest you change the
handleFileSelect
to just takefiles
.Then your test should be just:
And your component will just:
Here's an example that shows how both usages do not trigger an error in the compiler.