I got something like these lines of code:
jQuery('.js-img-input').on('change', handleNewFiles);
var handleNewFiles = function(event) {
var fileList = event.target.files;
loadFileList(fileList);
};
var loadFileList = function(fileList) {
jQuery(fileList).each(function(key, file) {
readFileAsync(file);
});
}
var readFileAsync = function(file) {
var fileReader = new FileReader();
fileReader.addEventListener("load", function(event) {
file.result = event.target.result;
saveFile(file);
});
fileReader.readAsDataURL(file);
};
All of the methods are private inside a jQuery-function and I don't whant to make "handleNewFiles" public just for testing purpose.
I would love to test these lines with something like this:
it('should create a fileReader', function(){
spyOn(window, 'FileReader').and.returnValue({
addEventListener: function(){},
readAsDataURL: function(){}
});
jQuery('.js-img-input').trigger('change');
expect(window.FileReader).toHaveBeenCalled();
});
But how did I get some dummy data into event.target.files?
Alright I find a solution. You can't create a faked native event with files and for security reasons that's a good thing. But in my case the solution looks like this:
it('should create a fileReader', function(){
var onChangeCallback;
spyOn(jQuery.fn, 'on').and.callFake(function(eventName, callback){
if(eventName === 'change'){
onChangeCallback = callback;
}
});
spyOn(window, 'FileReader').and.returnValue({
addEventListener: function(){},
readAsDataURL: function(){}
});
onChangeCallback({target:{files:[1,2,3]}});
expect(window.FileReader).toHaveBeenCalled();
});
While you can't assign a value to fileInput.files
, you can replace the property with your own, which accomplishes the same thing:
it('should create a fileReader', () => {
const fileInput = $('input[type=file]');
const fileInputElement = fileInput.get(0);
Object.defineProperty(fileInputElement, 'files', {
value: [{name: 'file.txt'}],
writable: false,
});
fileInput.trigger('input').trigger('change');
// expect outputs...
});
This is a bit better than creating your own event object, since it simulates the real environment a little more closely.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With