我们最近开始在 Controller 中加入 promise ,以同时处理多个请求,并且它可以在应用程序中工作,但是单元测试已被证明非常困难,我将很难准确掌握它的含义是我失踪了。以下是两个片段,它们非常简化了我正在尝试测试的内容。
Controller :
angular.module('testengine').controller('testController', [
'$scope',
'$q',
'Api',
function($scope, $q, Api) {
$scope.getTest = function (deferred) {
// do stuff...
Api.test.get(params, function(response) {
// do stuff with response
if (deferred) {
deferred.resolve(); // if success
}
});
};
$scope.runTest = function () {
// do stuff...
var promises = [];
var deferred = $q.defer();
promises.push(deferred.promise);
$scope.getTest(deferred);
$q.all(promises).then(function () {
$scope.navigate();
}, function () {
// do stuff with rejected
});
};
$scope.navigate = function () {
// do stuff
};
}]);
测试:
describe('Controller:', function () {
var root, scope, controllerFactory, $q;
function createController () {
return controllerFactory('testController', {
$scope: scope
});
}
beforeEach(function () {
module('testengine');
});
beforeEach(inject(function ($rootScope, $controller, _$q_) {
root = $rootScope;
scope = $rootScope.new();
controllerFactory = $controller;
$q = _$q_;
});
it('should run test', function () {
createController();
var deferred = $q.defer();
spyOn(scope, 'getTest').andReturn(deferred.resolve());
spyOn(scope, 'navigate');
$scope.runTest();
root.$apply();
expect(scope.navigate).toHaveBeenCalled();
});
});
根据我读过的关于 Promise 和 $q 的所有示例和文档,这应该可行,但事实并非如此,相反我得到:
Expected spy navigate to have been called but it was never called.
我猜测是因为它与我在模拟 spy 中解析的延迟对象不同,但我该如何模拟它呢?我是否必须将延迟对象绑定(bind)到 Controller 或范围或其他什么上?
您看到的结构的原因是因为有不同的方法使用 getTest() (有些方法不仅使用该请求,还使用其他方法,因此是 promise )。另外, getTest() 在另一个测试中单独测试,这就是为什么我想模拟该函数以及其中发出的任何请求。
感谢任何帮助,如果我犯了一些明显的错误,我很乐意自学,因为我对 Angular 还很陌生。
最佳答案
是的,您没有兑现正确的 promise 。您需要拦截函数参数。
spyOn(scope, 'getTest');
expect(scope.getTest).toHaveBeenCalled();
scope.getTest.mostRecentCall.args[0].resolve();
这是一个很好的简洁 Jasmine 引用:http://tobyho.com/2011/12/15/jasmine-spy-cheatsheet/
关于javascript - AngularJS Controller 中的单元测试 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22986782/