【发布时间】:2015-07-12 08:34:57
【问题描述】:
我在 AngularJS 中有以下控制器,它从 Angular Material 调用“$mdSidenav”提供的服务。这是由工厂方法提供的服务。
angular.module('leopDirective', [])
.controller('MenuCtrl', function ($scope,$timeout,$mdSidenav,$log) {
$scope.mdSidenav = $mdSidenav;
$scope.close = function () {
$mdSidenav('left').close().then(function() {$scope.closed=true; });
};
});
我正在尝试模拟该服务 ($mdSidenav) 以测试我的控制器。以下是我试图定义的 Jasmine 测试的源代码:
describe('Controller: MenuCtrl', function() {
var $rootScope, $scope, $controller, $q, menuCtrl,
mock__mdSidenav = function(component) {
return {
// THIS FUNCTION IS EMPTY SINCE $Q IS NOT AVAILABLE
close: function() {}
}
};
beforeEach(function() {
module('leopDirective', function($provide) {
// I HAVE TO PROVIDE THE MOCK UP BEFORE INJECTING $Q
$provide.value('$mdSidenav', mock__mdSidenav);
});
inject(function($injector) {
$rootScope = $injector.get('$rootScope');
$controller = $injector.get('$controller');
$q = $injector.get('$q');
$scope = $rootScope.$new();
});
menuCtrl = $controller("MenuCtrl", { $scope: $scope });
});
it('should create the $mdSidenav object', function() {
var deferred = $q.defer(),
promise = deferred.promise;
// NOW THAT $Q IS AVAILABLE, I TRY TO FILL UP THE FUNCTION
mock__mdSidenav.close = function() {
return promise.then(function(response){return response.success;});
};
// force `$digest` to resolve/reject deferreds
$rootScope.$digest();
// INVOKE FUNCTION TO TEST
$scope.close();
});
});
我的问题是我不知道如何为返回承诺的模拟创建一个函数:
- 创建承诺取决于 $q,
- $q 必须从“inject”块中注入,
- 但是,$provide 必须在“模块”中使用,就在“注入”之前,
- 因此,在我的模拟对象 (mock__mdSidenav().close()) 中返回承诺的函数在调用“$provide”之前必须为空,并且以某种方式稍后创建。
使用这种方法,我得到的错误是以下错误(参见 Demo plnkr),它告诉我先创建空函数然后再填充它不起作用:
TypeError: Cannot read property 'then' of undefined
at Scope.$scope.close (app.js:7:35)
模拟具有返回承诺的函数的服务的正确方法是什么?
【问题讨论】:
标签: javascript angularjs unit-testing mocking jasmine