我使用服务在控制器之间共享数据。如果服务上的值发生更改,我想更新控制器上的某些数据绑定。要做到这一点,我使用$ scope。$ watchCollection(因为我观看的值是一个简单的数组)。我在试图弄清楚如何在Jasmine + Karma中测试它时遇到了麻烦。
这是一个简单的Controller + Service设置,类似于我在我的应用中所做的事情(但非常简化):
var app = angular.module('myApp', []);
// A Controller that depends on 'someService'
app.controller('MainCtrl', function($scope, someService) {
$scope.hasStuff = false;
// Watch someService.someValues for changes and do stuff.
$scope.$watchCollection(function(){
return someService.someValues;
}, function (){
if(someService.someValues.length > 0){
$scope.hasStuff = false;
} else {
$scope.hasStuff = true;
}
});
});
// A simple service potentially used in many controllers
app.factory('someService', function ($timeout, $q){
return {
someValues: []
};
});
以下是我尝试过的测试用例(但不起作用):
describe('Testing a controller and service', function() {
var $scope, ctrl;
var mockSomeService = {
someValues : []
};
beforeEach(function (){
module('myApp');
inject(function($rootScope, $controller) {
$scope = $rootScope.$new();
ctrl = $controller('MainCtrl', {
$scope: $scope,
someService: mockSomeService
});
});
});
it('should update hasStuff when someService.someValues is changed', function (){
expect($scope.hasStuff).toEqual(false);
// Add an item to someService.someValues
someService.someValues.push(1);
//$apply the change to trigger the $watch.
$scope.$apply();
//assert
expect($scope.hasStuff).toEqual(true);
});
});
我想我的问题有两个:
如何正确模拟控制器中使用的服务? 我如何测试$ watchCollection函数是否正常工作?
这是上面代码的一个plunkr。 http://plnkr.co/edit/C1O2iO
答案 0 :(得分:1)
您的测试(或您的代码)不正确。
http://plnkr.co/edit/uhSdk6hvcHI2cWKBgj1y?p=preview
mockSomeService.someValues.push(1); // instead of someService.someValues.push(1);
和
if(someService.someValues.length > 0){
$scope.hasStuff = true;
} else {
$scope.hasStuff = false;
}
或者你的期望毫无意义
我强烈建议你用你的javascript(jslint / eslint / jshint)来发现像第一个这样的愚蠢错误。或者你在编写javascript时会有痛苦的经历。 jslint会检测到您使用的变量在范围内不存在。