2013-03-04 95 views
12

我试图做这个测试工作,但我无法得到我的头如何用FileReader写一个测试。这是我的代码如何在Jasmine中编写FileReader测试?

 

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); 
      } 
     } 
    }; 
})(); 


 

这是我的测试

 

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"); 
    }) 
}); 
 

但它永远不会获取reader.onload

回答

10

这里的问题是使用reader.onload这是很难测试。你可以使用reader.addEventListener代替你可以窥视全球的FileReader对象,并返回一个模拟:

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

,那么你可以自己开火在onload回调:

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

我坚持这一点。任何人都可以提供一个工作示例吗我总是不确定(使用Karma/Angular/Jasmine)。 – 2014-12-09 17:35:25

+0

这实在是过时了。 – allenhwkim 2016-08-26 17:17:34

8

这句法在2.0改变。下面的代码给出了基于安德烈亚斯Köberle的回答一个例子,但使用新的语法

// create a mock object, its a function with some inspection methods attached 
    var eventListener = jasmine.createSpy(); 

    // this is going to be returned when FileReader is instantiated 
    var dummyFileReader = { addEventListener: eventListener }; 

    // pipe the dummy FileReader to the application when FileReader is called on window 
    // this works because window.FileReader() is equivalent to new FileReader() 
    spyOn(window, "FileReader").and.returnValue(dummyFileReader) 

    // your application will do something like this .. 
    var reader = new FileReader(); 

    // .. and attach the onload event handler 
    reader.addEventListener('load', function(e) { 

     // obviously this wouldnt be in your app - but it demonstrates that this is the 
     // function called by the last line - onloadHandler(event); 
     expect(e.target.result).toEqual('url'); 

     // jasmine async callback 
     done(); 
    }); 

    // if addEventListener was called on the spy then mostRecent() will be an object. 
    // if not it will be null so careful with that. the args array contains the 
    // arguments that addEventListener was called with. in our case arg[0] is the event name .. 
    expect(eventListener.calls.mostRecent().args[0]).toEqual('load'); 

    // .. and arg[1] is the event handler function 
    var onloadHandler = eventListener.calls.mostRecent().args[1]; 

    // which means we can make a dummy event object .. 
    var event = { target : { result : 'url' } }; 

    // .. and call the applications event handler with our test data as if the user had 
    // chosen a file via the picker 
    onloadHandler(event); 
+0

我发现奇怪的是,如果你在全局范围上隐式地创建FileReader,就像'new FileReader()',茉莉花找不到它,但是如果我调用'new window.FileReader()',那么间谍踢如预期的那样。花费我将近一个小时才能搞清楚。 – 2016-12-13 09:25:36

1

我发现最容易为自己接下来该怎么办。

  • 模拟BLOB文件
  • 运行reader.onload而在测试环境。

的结果 - 我不嘲笑的FileReader

// CONTROLLER 
 

 
$scope.handleFile = function (e) { 
 

 
      var f = e[0]; 
 

 
      $scope.myFile = { 
 
       name: "", 
 
       size: "", 
 
       base64: "" 
 
      }; 
 
      var reader = new FileReader(); 
 
      reader.onload = function (e) { 
 
         try { 
 
          var buffer = e.target.result; 
 
          $scope.myFile = { 
 
           name: f.name, 
 
           size: f.size, 
 
           base64: XLSX.arrayBufferToBase64(buffer) 
 
          }; 
 
          $scope.$apply(); 
 

 
         } catch (error) { 
 
          $scope.error = "ERROR!"; 
 
          $scope.$apply(); 
 
         } 
 
        }; 
 

 
reader.readAsArrayBuffer(f); 
 
//run in test env 
 
if (typeof jasmine == 'object') {reader.onload(e)} 
 
} 
 

 
//JASMINE TEST 
 

 
it('handleFile 0', function() { 
 

 

 
    var fileContentsEncodedInHex = ["\x45\x6e\x63\x6f\x64\x65\x49\x6e\x48\x65\x78\x42\x65\x63\x61\x75\x73\x65\x42\x69\x6e\x61\x72\x79\x46\x69\x6c\x65\x73\x43\x6f\x6e\x74\x61\x69\x6e\x55\x6e\x70\x72\x69\x6e\x74\x61\x62\x6c\x65\x43\x68\x61\x72\x61\x63\x74\x65\x72\x73"]; 
 
    var blob = new Blob(fileContentsEncodedInHex); 
 
    blob.type = 'application/zip'; 
 
    blob.name = 'name'; 
 
    blob.size = 11111; 
 
    var e = {0: blob, target: {result: {}}}; 
 

 
    $scope.handleFile(e); 
 
    expect($scope.error).toEqual(""); 
 

 
});

相关问题