我可能做错了,但我不知道如何解决它。
我想测试一个使用资源 (ngResource) 的 Controller ,并且我想使用 Spy 作为资源的测试替身,这样它实际上并不执行 http 调用。在下面的代码中我只想测试 Controller 中的搜索功能。
Controller :
controllers = angular.module('app.controllers');
controllers.controller('landingCtrl', ['$scope', '$q', 'categoryResource', function ($scope, $q, categoryResource) {
$scope.search = function (text) {
console.log('searching for: ' + text);
var deferred = $q.defer();
categoryResource.query({ searchTerm: text }, function (result) {
if (result.length == 0) {
deferred.resolve(['No results found']);
} else {
deferred.resolve(result);
}
});
return deferred.promise;
}
}]);
服务:
var services = angular.module('app.services');
services.factory('categoryResource', ['$resource', function ($resource) {
var resource = $resource('/api/category');
return resource;
}]);
登陆Ctrl的规范:
describe('Controller: landingCtrl ', function () {
var $q,
$rootScope,
$scope;
beforeEach(module('ngResource'));
beforeEach(module('app.services'));
beforeEach(module('app.controllers'));
beforeEach(inject(function (_$rootScope_, _$q_) {
$q = _$q_;
$rootScope = _$rootScope_;
}));
// mock any depencencies, like scope. $resource or $http
beforeEach(inject(function ($controller, $injector, categoryResource) {
$scope = $rootScope.$new();
spyOn(categoryResource, 'query').andCallFake(function (searchText) {
console.log('query fake being called');
var deferred = $q.defer();
deferred.resolve(['Test', 'Testing', 'Protester']);
return deferred.promise;
});
landingCtrl = $controller('landingCtrl', {
'$scope': $scope,
'$q': $q,
'categoryResource': categoryResource
});
}));
afterEach(inject(function ($rootScope) {
$rootScope.$apply();
}));
it('should return words with "test" in them"', function () {
$scope.search('test').then(function (results) {
console.log(results);
expect(results).toContain('Test');
});
$scope.$apply();
});
});
测试执行时没有错误,但它通过了,但没有解决 promise ,因此“then”函数中的我的代码永远不会被调用。我做错了什么?
我用上面的内容创建了一个 plunker 以及一个应该失败的测试:
最佳答案
您的规范正在模拟categoryResource.query()
,因此它返回一个 promise ,但您的 Controller 并不期望这样做。它调用 query()
并传递一个回调,并在该回调中执行其操作。换句话说,您的规范并未测试您的 Controller 的功能。
这是您的固定规范:
spyOn(categoryResource, 'query').andCallFake(function (searchText, callback) {
console.log('query fake being called');
callback(['Test', 'Testing', 'Protester']);
});
...
it('should return words with "test" in them"', function () {
var results;
$scope.search('test').then(function (_results_) {
console.log(results);
results = _results_;
});
$scope.$apply();
expect(results).toContain('Test');
});
请注意,我已将期望移至 then()
回调之外,因此如果 promise 未得到解决,您的测试就会中断。
关于javascript - Angularjs 单元测试解决 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30241329/