Javascript jasmine测试中函数内未定义的$scope变量
我最近开始学习angular应用程序的单元测试。而且已经面临问题了。我不能从内部执行的函数中获取Javascript jasmine测试中函数内未定义的$scope变量,javascript,angularjs,unit-testing,karma-jasmine,Javascript,Angularjs,Unit Testing,Karma Jasmine,我最近开始学习angular应用程序的单元测试。而且已经面临问题了。我不能从内部执行的函数中获取范围变量。这是我的工厂代码 angular.module('app').factory('AuthenticationService', AuthenticationService); AuthenticationService.$inject = ['$http']; function AuthenticationService($http) { var service = {};
范围
变量。这是我的工厂代码
angular.module('app').factory('AuthenticationService', AuthenticationService);
AuthenticationService.$inject = ['$http'];
function AuthenticationService($http) {
var service = {};
service.login = login;
return service;
function login(data, callback) {
$http({
method: 'POST',
url: CONFIG.getUrl('auth/login'),
data: data
}).then(function (response) {
callback(response);
}, function (error) {
callback(error);
});
}
我的控制器文件的一部分。我只想测试登录
功能
function AuthCtrl($scope, $location, AuthenticationService) {
var vm = this;
vm.login = login;
vm.dataLogin = {
user_id: '',
password: '',
};
function login() {
vm.dataLoading = true;
AuthenticationService.login(vm.dataLogin, function (response) {
if (response.status == 200) {
if (response.data.error_code == 'auth.credentials.invalid') {
vm.invalidCredentials = true;
} else {
vm.invalidCredentials = false;
if (response.data.session_state == 'otp_required') {
vm.userNumber = response.data.user_phone;
$localStorage['session_token'] = response.data.session_token;
vm.needForm = 'someForm';
} else {
AuthenticationService.setCredentials(response.data);
$state.go('dashboard');
}
vm.dataLoading = false;
}
}
});
}
}
});
还有我的spec.js
describe('AuthCtrl, ', function() {
var $scope, ctrl;
var authSrvMock;
var mockJson = {
user_id: '001',
session_token: 'some_token'
};
var mockLoginData = {
user_id: '0000102',
password: '123456'
};
var mockResponseData = {
data: {
"session_expires": 1453822506,
"session_state": "otp_required",
"session_token": "tokennnn",
"status": "success",
"user_id": "0000102",
"user_phone": "+7 (XXX) XXX-XX-89"
},
status: 200
};
beforeEach(function () {
authSrvMock = jasmine.createSpyObj('AuthenticationService', ['login', 'logout']);
module('app');
inject(function ($rootScope, $controller, $q) {
$scope = $rootScope.$new();
authSrvMock.login.and.returnValue(mockResponseData);
ctrl = $controller('AuthCtrl', {
$scope: $scope,
AuthenticationService: authSrvMock
});
});
});
it('should call login function and pass to dashboard', function () {
ctrl.login();
expect(authSrvMock.login).toHaveBeenCalled();
// until this everything works here just fine
});
});
但是在我想测试vm.invalidCredentials
之后,如果我要写
expect(ctrl.invalidCredentials).toBe(false)
我将得到错误
预期未定义为false。
为什么我看不到变量 我自己在Jasmine有点不爽,但我猜这是因为你需要从你的
login()
中得到承诺才能回到Jasmine
考虑一下如何使用,甚至。我自己在Jasmine也有点不妥,但我猜这是因为你需要从你的
登录()中得到承诺才能返回Jasmine
研究使用,甚至。经过更多的挖掘过程和实验,我找到了解决办法。
这就是我所做的
(function () {
'use strict';
describe('AuthCtrl', function () {
var controller, scope, myService, q, deferred, ctrl;
var mockResponseData = {
response1: {
//...
},
response2: {
//...
},
response3: {
//...
}
};
beforeEach(module('app'));
beforeEach(inject(function ($controller, $rootScope, $q, $httpBackend, AuthenticationService) {
function mockHttp(data, callback) {
deferred = $q.defer();
deferred.promise.then(function (response) {
callback(response);
}, function (error) {
callback(error);
});
}
controller = $controller;
scope = $rootScope.$new();
myService = AuthenticationService;
q = $q;
myService.login = mockHttp;
}));
describe('when returning promises', function () {
beforeEach(function () {
ctrl = controller('AuthCtrl', {
$scope: scope,
myService: myService
});
ctrl.initController();
});
it('shows another form to validate login process', function () {
ctrl.login();
deferred.resolve(mockResponseData.response1);
scope.$digest();
expect(ctrl.invalidCredentials).toBe(false);
expect(ctrl.needForm).toEqual('2sAuth');
expect(ctrl.dataLoading).toBe(false);
});
});
});
})();
因为在我的工厂里,几乎每个方法都需要数据
和回调
,所以我创建了mockHttp函数,它接受这些参数和延迟承诺。在it
模块中,我只需调用need函数,用我准备好的答案解决promise,并检查我的期望。一切正常。多亏了你的瞄准,在经过更多的挖掘过程和实验后,我找到了解决办法。
这就是我所做的
(function () {
'use strict';
describe('AuthCtrl', function () {
var controller, scope, myService, q, deferred, ctrl;
var mockResponseData = {
response1: {
//...
},
response2: {
//...
},
response3: {
//...
}
};
beforeEach(module('app'));
beforeEach(inject(function ($controller, $rootScope, $q, $httpBackend, AuthenticationService) {
function mockHttp(data, callback) {
deferred = $q.defer();
deferred.promise.then(function (response) {
callback(response);
}, function (error) {
callback(error);
});
}
controller = $controller;
scope = $rootScope.$new();
myService = AuthenticationService;
q = $q;
myService.login = mockHttp;
}));
describe('when returning promises', function () {
beforeEach(function () {
ctrl = controller('AuthCtrl', {
$scope: scope,
myService: myService
});
ctrl.initController();
});
it('shows another form to validate login process', function () {
ctrl.login();
deferred.resolve(mockResponseData.response1);
scope.$digest();
expect(ctrl.invalidCredentials).toBe(false);
expect(ctrl.needForm).toEqual('2sAuth');
expect(ctrl.dataLoading).toBe(false);
});
});
});
})();
因为在我的工厂里,几乎每个方法都需要数据
和回调
,所以我创建了mockHttp函数,它接受这些参数和延迟承诺。在it
模块中,我只需调用need函数,用我准备好的答案解决promise,并检查我的期望。一切正常。多亏了您的瞄准方式,才创造了一个完美的外观。它似乎没有进入登录功能(打开控制台并刷新预览)@JamieBarker,那么为什么会发生这种情况呢?我该怎么做才能进去?下决心还是承诺?你能解释一下吗。它似乎没有进入登录功能(打开控制台并刷新预览)@JamieBarker,那么为什么会发生这种情况呢?我该怎么做才能进去?下决心还是承诺?你能解释一下吗?