每次测试后重置服务对象
Reset service object after each test
我想在我的AngularJS应用程序中测试我的Auth服务。
这是服务:
'use strict';
angular.module('testApp')
.factory('Auth', function ($window, $http, $location, $q) {
var currentUser;
return {
authenticate: function (email, password) {
//promise to return
var deferred = $q.defer();
var authRequest = $http.post('https://' + $location.host() + ':3005/authenticate', {email: email, password: password});
authRequest.success(function (data, status, header, config) {
//Store currentUser in sessionStorage
currentUser = data;
$window.sessionStorage.setItem('currentUser', JSON.stringify(currentUser));
//resolve promise
deferred.resolve();
});
authRequest.error(function (data, status, header, config) {
//reject promise
deferred.reject('Invalid credentials.');
});
return deferred.promise;
},
isAuthenticated: function () {
return this.getCurrentUser() !== null;
},
getCurrentUser: function () {
if (currentUser !== undefined) {
return currentUser;
} else {
currentUser = JSON.parse($window.sessionStorage.getItem('currentUser'));
return currentUser;
}
},
logOut: function () {
var that = this;
$http.get('https://' + $location.host() + ':3005/logout')
.success(function (data, status, header, config) {
that.appLogOut();
$location.path('/login');
}).
error(function (data, status, headers, config) {
console.log('logout error');
});
},
appLogOut: function () {
console.log('appside log out');
currentUser = null;
$window.sessionStorage.removeItem('currentUser');
}
};
});
这是我的测试:
'use strict';
describe('Service: Auth', function () {
// load the service's module
beforeEach(module('testApp'));
// instantiate service and any mock objects
var Auth,
httpBackend;
//http://code.angularjs.org/1.2.14/docs/api/ngMock/function/angular.mock.inject
beforeEach(inject(function (_Auth_, $httpBackend) {
Auth = _Auth_;
httpBackend = $httpBackend;
}));
// verify that no expectations were missed in the tests
afterEach(function () {
httpBackend.verifyNoOutstandingExpectation();
httpBackend.verifyNoOutstandingRequest();
});
it('should be instantiated', function () {
(!!Auth).should.be.true;
});
describe('authenticate(email, password)', function () {
var user = {
email: 'shaun@test.com',
password: 'password',
sessionId: 'abc123'
};
it('should make a call to the server to log the user in - and FULFILL promise if response == 200', function () {
httpBackend.whenPOST(/https:'/'/.+'/authenticate/, {
email: user.email,
password: user.password
}).respond(200, user);
var promise = Auth.authenticate(user.email, user.password);
httpBackend.flush();
promise.should.eventually.be.fulfilled;
});
});
describe('isAuthenticated()', function () {
it('should return false if user is not authenticated', function () {
Auth.isAuthenticated().should.be.false;
});
});
describe('logOut()', function () {
it('should make a call to the server to log the user out', function () {
// expect a GET request to be made
// regex to capture all requests to a certain endpoint regardless of domain.
httpBackend.expectGET(/https:'/'/.+'/logout/).respond(200);
// call the logOut method on Auth service
Auth.logOut();
// flush to execute defined mock behavior.
httpBackend.flush();
});
});
});
我的问题是以下测试:
describe('isAuthenticated()', function () {
it('should return false if user is not authenticated', function () {
Auth.isAuthenticated().should.be.false;
});
});
根据我的理解,每个"描述"和/或"它"块应该是完全独立的。我认为在每次测试之前注入一个新的Auth实例。但是,由于在此测试运行之前身份验证测试成功,因此上述测试失败。
因此输出变成:
Chrome 33.0.1750 (Mac OS X 10.8.2) Service: Auth isAuthenticated() should return false if user is not authenticated FAILED
expected true to be false
AssertionError: expected true to be false
我错过了什么?每次测试后我必须手动重置Auth对象吗?我尝试在afterEach()函数中设置Auth ={},但这似乎没有改变任何东西。
感谢您花时间阅读这个问题。
更新:
我知道问题所在。在Auth.getCurrentUser()中,我从$window.sessionStorage抓取"currentUser"。因此,我确实获得了Auth的每个测试的新实例(我认为),但相同的$window实例。sessionStorage正在被使用
问题现在应该是…"我如何清除$window ?"
我最终模拟了$window对象:
beforeEach(function () {
// $window mock.
windowMock = {
sessionStorage: {
getItem: sinon.stub(),
setItem: sinon.spy(),
removeItem: sinon.spy()
}
};
// stub out behavior
windowMock.sessionStorage.getItem.withArgs('currentUser').returns(JSON.stringify(user));
module(function ($provide) {
$provide.value('$window', windowMock);
});
});
测试示例:
windowMock.sessionStorage.setItem.calledWith('currentUser', JSON.stringify(user)).should.be.true;
windowMock.sessionStorage.setItem.neverCalledWith('currentUser', JSON.stringify(user)).should.be.true;
相关文章:
- 如何将javascript对象作为参数传递到c#web服务中
- 对象未从Ionic服务正确返回
- 为什么Angularjs服务返回的是字符数组而不是对象数组
- 关注点,装饰者,演示者,服务对象,帮助者-帮助我理解他们
- 角度控制器不绑定服务对象属性 ng-repeat
- 表示不将对象从服务发送到 API 控制器
- 为什么从 Angular 服务中的对象中删除此元素不起作用
- 将工厂/服务对象隔离到单个元素's指令
- 利用谷歌分析API与Javascript -生成服务对象
- Angular,如何停止对服务对象的跟踪
- AngularJS:服务对象为空
- 将指向服务对象属性的指针/引用添加到$scope变量
- Typescript中为angular指令输入错误的服务对象
- 在异步(ajax)调用后将服务/对象注入控制器
- 更新angular.js服务对象,无需扩展/复制
- SP服务-对象不'我不支持这种方法
- 每次测试后重置服务对象
- 在angularjs中,认证服务对象在刷新时会丢失页面
- AngularJS:如何观察服务对象
- 将Web服务对象列表转换为数组的数组