2013-03-04 10 views
12

Sto provando a far funzionare questo test, ma non riuscivo a capire come scrivere un test con FileReader. Questo è il mio codiceCome posso scrivere il test FileReader in Jasmine?

 

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


 

E questa è la mia prova

 

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

Ma non è mai arriva a reader.onload.

risposta

10

Il problema qui è l'uso di reader.onload che è difficile da testare. Si potrebbe utilizzare reader.addEventListener invece in modo da poter spiare l'oggetto FileReader globale e restituire un finto:

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

allora si può sparare il callback onload da soli:

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

mi sono bloccato su questo. Qualcuno può fornire un esempio funzionante? Sto sempre diventando indefinito (usando Karma/Angular/Jasmine). –

+0

questo è davvero obsoleto. – allenhwkim

8

Questa sintassi cambiato in 2.0. Codice qui sotto mostra un esempio in base alla risposta di Andreas Köberle ma utilizzando la nuova sintassi

// 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

Ho scoperto che, stranamente, se si crea implicitamente il FileReader sull'ambito globale, come 'new FileReader()', jasmine non riesce a trovarlo, ma se chiamo 'new window.FileReader()' allora i calci spia come previsto. Mi è costato quasi un'ora per capirlo. –

1

ho trovato più facile per me fare dopo.

  • finto file di blob
  • corsa reader.onload mentre in ambiente di test.

come risultato - io non rido 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(""); 
 

 
});

Problemi correlati