如何使用一个函数测试Angular控制器,该函数可以在不嘲笑AJAX调用的情况下进行AJAX调用
How to test an Angular controller with a function that makes an AJAX call without mocking the AJAX call?
我在控制器中有一个函数,它调用一个服务,该服务又调用另一个服务。该服务进行AJAX调用并返回promise。简单地说:
MainController
call = function(){
//Handle the promise here, update some configs and stuff
someService.call().then(success, failure);
}
SomeService
return {
call: function(){
return SomeOtherService.call();
}
}
SomeOtherService
return {
call: function(){
return $http.get(someUrl);
}
}
如何在不进行AJAX调用的情况下测试主控制器的调用函数?我显然会单独测试这些服务。
更新:所以我按照下面的答案进行了更改,这就是我得到的:
angular.module('myApp')
.controller('LoginCtrl', ['$scope', '$location', 'AuthService', '$state', function ($scope, $location, AuthService, $state) {
$scope.user = {};
$scope.login = function(user) {
$scope.user = user;
//This login function in turn calls the 'authenticate' from another service 'Ajax' and the promise is handled here.
AuthService.login($scope.user)
.then(function() {
$scope.loginStatus = {
message : 'Login successful',
alertClass : 'success'
};
$state.go('app.dashboard');
}, function() {
$scope.loginStatus = {
message : 'Unauthorized access.',
alertClass : 'danger'
};
});
};
$scope.closeAlert = function() {
$scope.loginStatus = false;
};
}]);
PhantomJS 1.9.7 (Linux) Controller: LoginCtrl should call login FAILED
TypeError: 'undefined' is not an object (evaluating 'AuthService.login($scope.user)
.then')
at /home/rutwickg/Projects/workspace/myProject/app/scripts/controllers/login.js:15
at /home/rutwickg/Projects/workspace/myProject/test/spec/controllers/login.js:34
at /home/rutwickg/Projects/workspace/myProject/node_modules/karma-jasmine/lib/boot.js:117
at /home/rutwickg/Projects/workspace/myProject/node_modules/karma-jasmine/lib/adapter.js:171
at http://localhost:8080/karma.js:189
at http://localhost:8080/context.html:145
这就是我当前代码的样子:
'use strict';
describe('Controller: LoginCtrl', function() {
// load the controller's module
beforeEach(module('sseFeApp'));
var LoginCtrl,
scope,
authMock,
ajaxMock,
q;
// Initialize the controller and a mock scope
beforeEach( inject(function($controller, $rootScope, _AuthService_, _Ajax_, $q) {
authMock = _AuthService_;
ajaxMock = _Ajax_;
q = $q;
scope = $rootScope.$new();
LoginCtrl = $controller('LoginCtrl', {
$scope: scope
});
}));
it('should call login', function() {
var deferred = q.defer();
spyOn( authMock, 'login').and.returnValue(deferred.promise);
$scope.login({username: 'Sample', password: 'Sample'});
deferred.reject({});
expect( authMock.login ).toHaveBeenCalled();
//expect( ajaxMock.login).toHaveBeenCalled(); //Expect the second service call
});
});
更新:根据新语法,它应该是and.returnValue(deferred.promise)
。作品
您只需在所调用的函数上注入自己的Service和Spy。
describe( 'Controller: myCtrl', function () {
var myService,
...;
beforeEach( inject( function ( _myService_ ) {
...
myService = _myService_;
...
} ) );
it( 'should call myService.call', inject(function ($q)
{
var deferred = $q.defer();
spyOn( myService, 'call' ).andReturn(deferred.promise);
// .and.returnValue() for jasmine 2.0
$scope.myControllerFn();
deferred.resolve( {} ); // for success
// deferred.reject() --> for error
$scope.digest(); // do this if you want success/error to be executed.
expect( myService.call ).toHaveBeenCalled();
} );
} );
相关文章:
- 是否可以将一个函数输入连接到另一个函数调用的文本
- 在输入字段上有两个函数调用,一个在Blur上,一个不在Angular中
- 如何在Javascript函数调用中循环变量
- Javascript:应为赋值或函数调用,但实际看到的却是表达式
- 如何远程检查JavaScript应用程序的函数调用堆栈
- javascript函数调用不起作用
- 为什么这个函数调用会破坏程序并导致未定义的变量
- 如何通过函数调用设置图像的src
- 从全局函数调用Ember控制器上的方法
- 为什么Jquery$.ajax在函数调用中触发所有statusCode,即使调用成功
- JavaScript函数调用(arg1)(arg2)
- 打印链接时,将javascript函数调用到链接中
- 在函数调用中封装数据除了隐藏数据之外还有什么优点
- 无法从JavaScript中的函数调用对象属性
- 对中的函数调用进行排序是回调的唯一方法
- 函数调用方法有什么用
- Javascript:JSHint:应为赋值或函数调用,但实际看到的却是表达式
- HTML5(Bootstrap)通过函数调用运行动画
- 函数调用不起作用
- 函数中的Javascript函数调用