我想知道哪种方法可以测试不返回任何内容的函数(只是更改字段值)并包含异步调用。
这是我要测试的AngularJS控制器,我调用的服务返回一个promise(总是返回{name:“John”}):
app.controller('MyCtrl', function($scope, AsyncService) {
$scope.greeting = "";
$scope.error =
$scope.sayHello = function() {
AsyncService.getName().then(
function(data){
$scope.saludo = "Hello " + data.name;
},
function(data){
$scope.error = data;
}
);
};
});
如果sayHello函数不包含异步调用,那么这将是规范,但它总是失败,因为scope.greeting总是为空。
describe('Test My Controller', function() {
var scope, $httpBackend;
// Load the module with MainController
//mock Application to allow us to inject our own dependencies
beforeEach(angular.mock.module('app'));
//mock the controller for the same reason and include $rootScope and $controller
beforeEach(angular.mock.inject(function($rootScope, $controller,_$httpBackend_){
//Mock the service to always return "John"
$httpBackend = _$httpBackend_;
$httpBackend.when('POST', 'http://localhost:8080/greeting').respond({name: "John"});
//create an empty scope
scope = $rootScope.$new();
//declare the controller and inject our empty scope
$controller('MyCtrl', {$scope: scope});
}));
it('$scope.greeting should get filled after sayHello', function() {
expect(scope.greeting).toEqual("");
scope.sayHello();
expect(scope.greeting).toEqual("Hello John");
});*/
});
我如何制作此规范来处理异步调用?我真的不明白如何以及在哪里使用Jasmine 2.0的“完成”标志。
答案 0 :(得分:1)
使用$ q.defer()在模拟服务时从getName
函数返回一个承诺。然后在创建控制器时将模拟传递给依赖项:
beforeEach(inject(function($controller, _$rootScope_, $q) {
$rootScope = _$rootScope_;
deferred = $q.defer();
asyncService = {
getName: function () {
}
};
spyOn(asyncService, 'getName').and.returnValue(deferred.promise);
$scope = $rootScope.$new();
createController = function() {
return $controller('MyCtrl', { $scope: $scope, AsyncService: asyncService } );
};
}));
然后在致电$scope.hello()
之后致电deferred.resolve(data)l
,其中数据是您希望从承诺中的服务返回的数据。然后拨打$rootScope.$digest();
it('$scope.saludo should get filled after sayHello', function() {
//Arrange
var controller = createController();
var data = {
name: 'John'
};
//Act
$scope.sayHello();
deferred.resolve(data);
$rootScope.$digest();
//Assert
expect($scope.saludo).toEqual('Hello ' + data.name);
});