目前我在为角度控制器编写单元测试时遇到困难。我有一个$scope
函数,它生成一个ajax请求,在解析所有promise之后,它将获取的数据分配给$scope.products
。但它对我不起作用,我也不知道我在这里做错了什么!
$scope.products = [];
// $q.all is used because i've some other data sources too
$scope.query = function (term) {
$q.all([
DataService.autocomplete.products(term)
]).then(function (results) {
$scope.products = results[0].data.content;
});
};
// dataservice return value
return {
autocomplete: {
products: function (term) {
// _makeRequest is a wrapper for a $http call
return _makeRequest('autocomplete/products', term);
}
}
}
describe('[Autocomplete] AutocompleteCtrl', function () {
var $scope, DataService;
beforeEach(module('Autocompleter'));
beforeEach(inject(function ($rootScope, $controller, _$q_, _DataService_) {
var deferred = _$q_.defer();
$scope = $rootScope.$new();
DataService = _DataService_;
$controller('AutocompleteCtrl', {$scope: $scope});
deferred.resolve(['resolveData']);
spyOn(DataService.autocomplete, 'products').and.returnValue(deferred.promise);
}));
describe('Query', function () {
it('should resolve promise', function () {
$scope.query('term');
$scope.$apply();
expect($scope.products).toBe(['resolveData']);
});
});
});
TypeError: 'undefined' is not an object (evaluating 'results[0].data.content')
答案 0 :(得分:1)
您希望.data.content
的结果为DataService.autocomplete.products()
。
因此,您应该从以下位置更改模拟数据:
deferred.resolve(['resolveData']);
改为:
deferred.resolve({ data: { content: ['resolveData'] } });
希望这有帮助。
答案 1 :(得分:1)
您的控制器期望DataService.autocomplete.products()函数返回一个promise,并期望使用具有data
属性的对象解析此promise,因为您正在执行:
results[0].data.content
在测试中,您使用以下值解决假承诺:
['resolveData']
所以,而不是让对象看起来像
{
data:
{
content: 'someValue'
}
}
控制器收到['resolveData']
。
显然,访问['resolveData']
的数据属性会导致未定义的值。