我试图对处理用户签名的控制器进行单元测试。我收到错误并认为它可能与使用promises的代码有关但我并不是真的确定在这一点上。这是控制器。
angular.module('app').controller('SignIn', SignIn);
function SignIn ($scope, $state, auth) {
$scope.credentials = {};
// signin
$scope.signIn = function () {
auth.signIn($scope.credentials)
.then(function () {
$state.go('user.welcome');
}, function (res) {
$scope.signInError = res.statusText;
});
};
}
这是授权服务。
angular.module('app').factory('auth', auth);
function auth (session, api) {
return {
signIn : function (credentials) {
return api.signIn(credentials)
.then(function (res) {
session.create(res.data.sessionId, res.data.userName);
});
},
signout: function () {
return session.destroy();
},
isAuthenticated: function () {
return !!session.userName;
}
};
}
api只返回$ http promises。
signIn : function (credentials) {
return $http.post(base + '/auth/credentials', credentials);
}
会话只是一个存储当前会话信息的工厂,并将其保存到浏览器的cookie中。
这是我的茉莉花测试
describe('SignIn', function () {
// setup ------------------------------------------------------------------
// init app module
beforeEach(module('app'));
// inject Session service
beforeEach(angular.mock.inject(function (_$rootScope_, _$controller_, _auth_) {
$rootScope = _$rootScope_;
$scope = $rootScope.$new();
controller = _$controller_("SignIn", {$scope: $scope});
auth = _auth_;
}));
// setup spies
beforeEach(function () {
spyOn(auth, 'signIn');
});
// tests ------------------------------------------------------------------
// signin in
it("should call auth.signIn with the user's credentials", function () {
$scope.signIn();
expect(auth.signIn).toHaveBeenCalled();
});
});
我只是试图测试当你调用$ scope.signIn()时调用auth.signIn。应用程序本身工作但我在尝试运行此测试时遇到此错误。
SignIn should call auth.signIn with the user's credentials FAILED
TypeError: 'undefined' is not an object (evaluating 'auth.signIn($scope.credentials).then')
尽管存在期望,但当我调用$ scope.signIn()时会发生错误。如果我在$ scope.signIn()之前记录auth;被称为我得到这个。
LOG: Object{signIn: function () { ... }, signout: function () { ... }, isAuthenticated: function () { ... }}
所以我假设DI正在按预期工作。我已经看过不同的设置间谍的方法,但还没有弄明白实际上还有什么问题。任何帮助将不胜感激。
答案 0 :(得分:0)
这是因为你正在监视auth
的{{1}}功能。当你监视它时,它不再是你在api中的真正功能了。因此,您需要使用.and.returnValue发送来自间谍的承诺。
所以: -
signIn
<强> Plnkr 强>
如果你要为signIn(或任何其他函数的承诺,只做)返回一些值
beforeEach(inject(function (_$rootScope_, _$controller_, _auth_, _$q_) {
$rootScope = _$rootScope_;
$scope = $rootScope.$new();
controller = _$controller_("SignIn", {$scope: $scope});
auth = _auth_;
fakePromise = _$q_.when(); //get a fake promise
}));
beforeEach(function () {
spyOn(auth, 'signIn').and.returnValue(fakePromise); //return fakepromise
});