如何等待在AngularJS指令单元测试中执行回调?
我有一个简单的指令,可以很好地工作(用TypeScript编写,但实际上并不重要),它允许通过如何等待在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
和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();
});