在 karma、mocha 和 chai 中用 $q 和 angular 承诺
Promises with $q and angular in karma, mocha & chai
所以我试图让承诺在我的 angular 应用程序测试中工作,任何人都可以弄清楚我在这里做错了什么它不断返回:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
不知道是不是$q
仅供参考 我也尝试了 it('test', function(done){... done();})
控制器
(function() {
'use strict';
angular
.module('controller.editor', [])
.controller('EditorController', EditorController);
function EditorController($scope, $q) {
var vm = this;
angular.extend(vm, {
hack: hack
});
function hack(bool) {
return $q(function(resolve, reject) {
if (bool) {
resolve(true);
}
reject(false);
});
}
}
});
测试
describe('EditorController', function() {
var vm, scope, $controller, $rootScope, $injector;
beforeEach(function() {
module('app');
//Inject
inject(function(_$injector_) {
$injector = _$injector_;
$controller = $injector.get('$controller');
$rootScope = $injector.get('$rootScope');
// Create new scope object
scope = $rootScope.$new();
// Bind the controller
vm = $controller('EditorController', {
$scope: scope
});
});
});
describe('#addCustom', function() {
it('test', function(done) {
var aHack = vm.hack(true);
aHack.then(function(bool){
// Resolve
expect(bool).to.be.eq(true);
done();
}, function() {
// Reject
expect(bool).to.be.eq(false);
done();
});
});
});
});
问题是您的 Promise 在您设置 'then' 行为之前就已解决。
看看 these examples 都使用了 setTimeout。
在 angular 中测试承诺时,最佳做法是依靠 angular 机器来完成其工作以同步而不是异步地解决承诺。
这使得代码更易于阅读和维护。
它也不太容易出错;在 .then()
中做断言是一种反模式,因为如果永远不会调用回调,您的断言将永远不会 运行.
要使用 angular 测试方法,您应该:
- 移除
done
- 在测试中执行
$rootScope.$digest()
以解决 promise
- 做你的断言
将此应用于您的代码将是:
describe('#addCustom', function() {
it('test', function() {
var __bool = false;
var aHack = vm.hack(true).then(function(bool) {
__bool = bool;
});
$rootScope.$digest();
expect(__bool).to.be.eq(true);
});
});
但这很棘手,因为 $rootScope.$digest
仅解决 $q
承诺,而不是所有承诺,尤其不是通过 Promise()
构造函数从各种 es5 垫片创建的承诺,请参阅:
另请参阅:
http://brianmcd.com/2014/03/27/a-tip-for-angular-unit-tests-with-promises.html
所以我试图让承诺在我的 angular 应用程序测试中工作,任何人都可以弄清楚我在这里做错了什么它不断返回:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
不知道是不是$q
仅供参考 我也尝试了 it('test', function(done){... done();})
控制器
(function() {
'use strict';
angular
.module('controller.editor', [])
.controller('EditorController', EditorController);
function EditorController($scope, $q) {
var vm = this;
angular.extend(vm, {
hack: hack
});
function hack(bool) {
return $q(function(resolve, reject) {
if (bool) {
resolve(true);
}
reject(false);
});
}
}
});
测试
describe('EditorController', function() {
var vm, scope, $controller, $rootScope, $injector;
beforeEach(function() {
module('app');
//Inject
inject(function(_$injector_) {
$injector = _$injector_;
$controller = $injector.get('$controller');
$rootScope = $injector.get('$rootScope');
// Create new scope object
scope = $rootScope.$new();
// Bind the controller
vm = $controller('EditorController', {
$scope: scope
});
});
});
describe('#addCustom', function() {
it('test', function(done) {
var aHack = vm.hack(true);
aHack.then(function(bool){
// Resolve
expect(bool).to.be.eq(true);
done();
}, function() {
// Reject
expect(bool).to.be.eq(false);
done();
});
});
});
});
问题是您的 Promise 在您设置 'then' 行为之前就已解决。
看看 these examples 都使用了 setTimeout。
在 angular 中测试承诺时,最佳做法是依靠 angular 机器来完成其工作以同步而不是异步地解决承诺。
这使得代码更易于阅读和维护。
它也不太容易出错;在 .then()
中做断言是一种反模式,因为如果永远不会调用回调,您的断言将永远不会 运行.
要使用 angular 测试方法,您应该:
- 移除
done
- 在测试中执行
$rootScope.$digest()
以解决 promise - 做你的断言
将此应用于您的代码将是:
describe('#addCustom', function() {
it('test', function() {
var __bool = false;
var aHack = vm.hack(true).then(function(bool) {
__bool = bool;
});
$rootScope.$digest();
expect(__bool).to.be.eq(true);
});
});
但这很棘手,因为 $rootScope.$digest
仅解决 $q
承诺,而不是所有承诺,尤其不是通过 Promise()
构造函数从各种 es5 垫片创建的承诺,请参阅:
另请参阅:
http://brianmcd.com/2014/03/27/a-tip-for-angular-unit-tests-with-promises.html