toy toy - 10 months ago 344
Javascript Question

How do I write FileReader test in Jasmine?

I'm trying to make this test work, but I couldn't get my head around how to write a test with FileReader. This is my code



function Uploader(file) {
this.file = file;
}

Uploader.prototype = (function() {

function upload_file(file, file_contents) {
var file_data = new FormData()
file_data.append('filename', file.name)
file_data.append('mimetype', file.type)
file_data.append('data', file_contents)
file_data.append('size', file.size)

$.ajax({
url: "/upload/file",
type: "POST",
data: file_contents,
contentType: file.type,
success: function(){

// $("#thumbnail").attr("src", "/upload/thumbnail");

},
error: function(){
alert("Failed");
},
xhr: function() {
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',showProgress, false);
} else {
console.log("Upload progress is not supported.");
}
return myXhr;
}
});
}

return {
upload : function() {
var self = this,
reader = new FileReader(),
file_content = {};

reader.onload = function(e) {
file_content = e.target.result.split(',')[1];

upload_file(self.file, file_content);
}
}
};
})();





And this is my test



describe("Uploader", function() {
it("should upload a file successfully", function() {
spyOn($, "ajax");
var fakeFile = {};

var uploader = new Uploader(fakeFile);
uploader.upload();

expect($.ajax.mostRecentCall.args[0]["url"]).toEqual("/upload/file");
})
});



But it never gets to
reader.onload
.

Answer Source

The problem here is the use of reader.onload which is hard to test. You could use reader.addEventListener instead so you can spy on the global FileReader object and return a mock:

eventListener = jasmine.createSpy();
spyOn(window, "FileReader").andReturn({
 addEventListener: eventListener
})

then you can fire the onload callback by yourself:

expect(eventListener.mostRecentCall.args[0]).toEqual('load');
eventListener.mostRecentCall.args[1]({
  target:{
    result:'the result you wanna test'
  }
})