How to test input file with Jest and vue/test-utils
Solution 1
You could do this using the DataTransfer
object. Unfortunately, it hasn't been added to JSDOM, so you can't test in Jest. There's an open issue to add the object—https://github.com/jsdom/jsdom/issues/1568
If you ran your tests in a browser using Karma, you could test like this:
const wrapper = shallow(FormComponent)
const input = wrapper.find('input[type="file"]')
const dT = new ClipboardEvent('').clipboardData || new DataTransfer()
dT.items.add(new File(['foo'], 'programmatically_created.txt'))
input.element.files = dT.files
input.trigger('change')
Solution 2
If you're just wanting to simulate a value in input.element.files
and changes to input.element.value
in Jest, but not necessarily accurately simulating every DOM behavior, you can do it by defining a getter/setter for those fields. This works for me:
let localImageInput
let localImageInputFiles
let localImageInputValueGet
let localImageInputValueSet
let localImageInputValue = ''
beforeEach(function() {
localImageInput = wrapper.find('#local-image-input')
localImageInputFilesGet = jest.fn()
localImageInputValueGet = jest.fn().mockReturnValue(localImageInputValue)
localImageInputValueSet = jest.fn().mockImplementation(v => {
localImageInputValue = v
})
Object.defineProperty(localImageInput.element, 'files', {
get: localImageInputFilesGet
})
Object.defineProperty(localImageInput.element, 'value', {
get: localImageInputValueGet,
set: localImageInputValueSet
})
})
it('should do the thing', function() {
localImageInputValue = 'some-image.gif'
localImageInputFilesGet.mockReturnValue([{
size: 12345,
blob: 'some-blob',
width: 300,
height: 200
}])
localImageInput.trigger('change')
return Vue.nextTick().then(() => {
// Assuming the component sets input.value = '' when this event is triggered
// and calls someFn with the image data
expect(localImageInputValue).toEqual('')
expect(someFn.mock.calls[0][0]).toEqual({
size: 12345,
blob: 'some-blob',
width: 300,
height: 200
})
})
}
J.Correa
Desarrollador de software. Apasionado por la programación.
Updated on July 20, 2022Comments
-
J.Correa almost 2 years
I want to test file uploader component using Jest and vue/test-utils.
I have this:
describe('show progress bar of uploading file', () => { const wrapper = mount(FileUploaderComponent) // create csv file let csv = new Blob([''], { type: 'text/csv;charset=utf-8;' }) csv.name = 'myFile.csv' let input = wrapper.find('input') input.element.value = csv // || csv.error value, Error here input.trigger('change') // Update current status })
Where in FileUploaderComponent i have:
<template> <form action="POST" enctype="multipart/form-data"> <label class="btn btn-primary" for="input-file"> <input class="input-file" id="input-file" name="file" type="file" accept=".xlsx, .xls, .csv"> UPLOAD FILE </label> </form> </template>
Throws this error:
InvalidStateError: This input element accepts a filename, which may only be programmatically set to the empty string.
49 | 50 | let input = wrapper.find('input') > 51 | input.element.value = csv 52 | input.trigger('change') 53 | 54 | // Update current status
So, the question is: How can i trigger event change with file input value? in this case, a csv file as value ?
-
Vince Varga over 5 yearsany changes on this front?
-
chrismarx over 5 yearssame question, I don't care about testing progress, just the ability to set a file input value
-
vedsil about 4 yearsIs there anything I need to import in order to use ClipboardEvent? My program throws an error that it can't find it, even though I have the npm typescript module installed.
-
vedsil almost 4 years@Anand not yet unfortunately