Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何等待在AngularJS指令单元测试中执行回调?_Angularjs_Typescript_Jasmine_Karma Jasmine - Fatal编程技术网

如何等待在AngularJS指令单元测试中执行回调?

如何等待在AngularJS指令单元测试中执行回调?,angularjs,typescript,jasmine,karma-jasmine,Angularjs,Typescript,Jasmine,Karma Jasmine,我有一个简单的指令,可以很好地工作(用TypeScript编写,但实际上并不重要),它允许通过和HTML5文件API获得上传文件的内容 使用方法很简单: <body ng-controller="MyCtrl as ctrl"> <input type="file" file-read="ctrl.readInputFile(data)"> </body> 在这种情况下,更优雅的是: it('should call a callback each tim

我有一个简单的指令,可以很好地工作(用TypeScript编写,但实际上并不重要),它允许通过
和HTML5文件API获得上传文件的内容

使用方法很简单:

<body ng-controller="MyCtrl as ctrl">
  <input type="file" file-read="ctrl.readInputFile(data)">
</body>
在这种情况下,更优雅的是:

it('should call a callback each time a file has been read', done => {
  const el = compileTemplate(
    '<input type="file" file-read="readInputFile(data)">'
  );

  const files = new Array<string>();

  scope.readInputFile = (data: any) => {
    files.push(data);
    if (files.length === 2) {
      expect(files[0]).toEqual('data0');
      expect(files[1]).toEqual('data1');
      done();
    }
  };

  el.triggerHandler({
    type: 'change',
    target: {
      files: [
        new Blob(['data0']),
        new Blob(['data1'])
      ]
    }
  });

  scope.$digest();
});

因此,如果代码中断,单元测试将失败=>job done:)

您可以将
expect
函数放入回调函数。

我不使用Jasime,我总是使用mocha+chaijs+sinon,但jasmine也实现了
done
函数,它应该是这样工作的:

it('async method', function(done){ 
//once we add the done param, karma will wait until the fn is executed

 service.doSomethingAsync()
  .then(function(){
    //assertions 
    // expect(result).to.be.something();
    done(); //Where we are telling karma that it can continue with the test
  }
  //Other assertions    
}
beforeEach(function(done) {
    inject((_$compile_: angular.ICompileService, _$rootScope_: angular.IRootScopeService) => {
        $compile = _$compile_;
        $rootScope = _$rootScope_;
        scope = $rootScope.$new();
    });
    let el = compileTemplate('<input type="file" file-read="readInputFile(data)">');
    let files = new Array<string>();

    scope.readInputFile = (data: any) => {
        files.push(data);
    };

    el.triggerHandler({
        type: 'change',
        target: {
            files: [
                new Blob(['data0']),
                new Blob(['data1'])
            ]
        }
    });

    scope.$digest();

    done();
});
使用:


你用的是什么版本的茉莉花

如果是1.3,您可以使用等待一段时间,然后在规范中声明:

所以

变成

let files = new Array<string>();

runs(function() {
    scope.readInputFile = (data: any) => {
        files.push(data);
    };

    el.triggerHandler({
        type: 'change',
        target: {
            files: [
                new Blob(['data0']),
                new Blob(['data1'])
            ]
        }
    });

    scope.$digest();
});
waitsFor(function() {
    expect(files.length).toEqual(2);
    expect(files[0]).toEqual('data0');
    expect(files[1]).toEqual('data1');
}, "failure message", time_in_milliseconds);
如果您使用的是Jasmine 2.0,则可以使用以下功能:

您可以在每次之前将要测试的代码(以及它所依赖的任何设置代码)移动到
,在那里调用异步代码,然后在异步代码完成时通过调用
done
方法通知框架异步操作已完成。在调用
完成后自动运行您的规格。我以前从未使用过这个(我仍然在1.3)并且我不使用角度或业力,所以我在一个有点不熟悉的领域

根据,您的
before每个
函数应如下所示:

it('async method', function(done){ 
//once we add the done param, karma will wait until the fn is executed

 service.doSomethingAsync()
  .then(function(){
    //assertions 
    // expect(result).to.be.something();
    done(); //Where we are telling karma that it can continue with the test
  }
  //Other assertions    
}
beforeEach(function(done) {
    inject((_$compile_: angular.ICompileService, _$rootScope_: angular.IRootScopeService) => {
        $compile = _$compile_;
        $rootScope = _$rootScope_;
        scope = $rootScope.$new();
    });
    let el = compileTemplate('<input type="file" file-read="readInputFile(data)">');
    let files = new Array<string>();

    scope.readInputFile = (data: any) => {
        files.push(data);
    };

    el.triggerHandler({
        type: 'change',
        target: {
            files: [
                new Blob(['data0']),
                new Blob(['data1'])
            ]
        }
    });

    scope.$digest();

    done();
});

再说一次,我不使用angular、TypeScript或Karma,所以您可能需要对此进行调整。但这是总的想法;设置所有内容,运行异步代码,在设置中调用
done
,在规范中运行断言,调用
done

当回调不再被调用时,测试将自动失败=>您刚刚终止了测试代码的全部目的。
let files = new Array<string>();

scope.readInputFile = (data: any) => {
  files.push(data);
};

el.triggerHandler({
  type: 'change',
  target: {
    files: [
      new Blob(['data0']),
      new Blob(['data1'])
    ]
  }
});

scope.$digest();
let files = new Array<string>();

runs(function() {
    scope.readInputFile = (data: any) => {
        files.push(data);
    };

    el.triggerHandler({
        type: 'change',
        target: {
            files: [
                new Blob(['data0']),
                new Blob(['data1'])
            ]
        }
    });

    scope.$digest();
});
expect(files.length).toEqual(2);
expect(files[0]).toEqual('data0');
expect(files[1]).toEqual('data1');
waitsFor(function() {
    expect(files.length).toEqual(2);
    expect(files[0]).toEqual('data0');
    expect(files[1]).toEqual('data1');
}, "failure message", time_in_milliseconds);
beforeEach(function(done) {
    inject((_$compile_: angular.ICompileService, _$rootScope_: angular.IRootScopeService) => {
        $compile = _$compile_;
        $rootScope = _$rootScope_;
        scope = $rootScope.$new();
    });
    let el = compileTemplate('<input type="file" file-read="readInputFile(data)">');
    let files = new Array<string>();

    scope.readInputFile = (data: any) => {
        files.push(data);
    };

    el.triggerHandler({
        type: 'change',
        target: {
            files: [
                new Blob(['data0']),
                new Blob(['data1'])
            ]
        }
    });

    scope.$digest();

    done();
});
it('should call a callback each time a file has been read by FileReader', (done) => {
    expect(files.length).toEqual(2);
    expect(files[0]).toEqual('data0');
    expect(files[1]).toEqual('data1');

    done();
});