单元测试FileReader.onload fn with Jasmine and angularjs

时间:2016-06-13 12:58:54

标签: javascript angularjs unit-testing jasmine

我有一个自定义指令,用于上传/导入二进制文件。该指令侦听<input type="file"../>元素上的更改事件。

所以现在我进行了一个触发更改事件的测试,该测试工作正常并且除了reader.onload() fn之外还有代码覆盖率。因此,有人可以指导我做什么,以便...onload() fn通过单元测试触发。

这是指令中的监听器:

element.bind('change', function(changeEvt){
  var reader = new FileReader();
  var result = {
    filename: changeEvt.target.files[0].name
  };

  reader.onload = function (loadEvent) {
    scope.$apply(function () {
      result.data = loadEvent.target.result;
      scope.fileSelected({content: result});
    });
  };

  reader.readAsArrayBuffer(changeEvt.target.files[0]);
});

到目前为止的测试:

describe('file import', function () {
beforeEach(inject(function ($compile) {
  scope.testOnFileSelected = jasmine.createSpy('testOnFileSelected');
  eventListener = jasmine.createSpy();
  spyOn(windowMock, 'FileReader').and.returnValue({
    addEventListener: eventListener,
    readAsArrayBuffer : function() {
      //return console.log(file);
    }
  });
  elm = angular.element('<div id="testImportBtn"><my-file-select-button id="testFileSelect" caption="buttonText" file-selected="testOnFileSelected(content)" ng-disabled="testDisabled"></my-file-select-button></div>');
  $compile(elm)(scope);
  scope.$digest();
}));

fit('should render the button and be visible', function () {
  var button = elm.find('#testFileSelect');
  button .triggerHandler({type: 'change', target: {files: [{name: 'some.tar.gz'}]}});
  expect(windowMock.FileReader).toHaveBeenCalled();
  //expect(eventListener).toHaveBeenCalled(); Fails 
  //expect(scope.testOnFileSelected).toHaveBeenCalledWith({data: {}, fileName: 'some.tar.gz'}); fails
});
});

以下是代码覆盖率的视图:

enter image description here

1 个答案:

答案 0 :(得分:2)

你可以在spy中添加onload函数,并在调用fileReader后直接调用。

      spyOn(window, 'FileReader').and.returnValue({
        onload: function() {
        },
        readAsArrayBuffer : function() {
          //return console.log(file);
        }
      });

和&#34;它&#34;阻止你可以像on,

那样调用onload函数
      var mockedLoadEvent = { //eventdetails }
      expect(window.FileReader).toHaveBeenCalled();
      window.FileReader().onload(mockedLoadEvent);

这将在控制器/服务中调用您的自定义onload函数。

以下完整代码:

describe('file import', function () {
  beforeEach(inject(function ($compile) {
     scope.testOnFileSelected = jasmine.createSpy('testOnFileSelected');
     eventListener = jasmine.createSpy();
     spyOn(window, 'FileReader').and.returnValue({
        onload: function() {
        },
        readAsArrayBuffer : function() {
          //return console.log(file);
        }
      });
      elm = angular.element('<div id="testImportBtn"><my-file-select-button id="testFileSelect" caption="buttonText" file-selected="testOnFileSelected(content)" ng-disabled="testDisabled"></my-file-select-button></div>');
      $compile(elm)(scope);
      scope.$digest();
   }));

   it('should render the button and be visible', function () {
      var button = elm.find('#testFileSelect');
      button .triggerHandler({type: 'change', target: {files: [{name: 'some.tar.gz'}]}});
      var mockedLoadEvent = { //eventdetails }
      expect(window.FileReader).toHaveBeenCalled();
      window.FileReader().onload(mockedLoadEvent);
   });
});