我有一个服务CurrentUser,它依赖于StorageFactory。在此服务的构造函数中,如果StorageFactory.get返回用户,我将用户设置为该用户,否则设置默认用户值。现在,我想测试一下。
我已成功完成这项工作,但我对我使用的方法不满意。我得到了这种方法的灵感here。
我已粘贴以下代码。如果您愿意,我还创建了一个要点here。我删除了代码中不相关的部分以避免分心。这是使用ES6类和模块编写的,但这不应对测试产生任何影响。
该方法的问题是模拟将用于所有测试,这可能不是一件坏事,但我想控制它。有没有办法让这个模拟只对这个测试产生影响? 找到更好方法的一个障碍是必须在angular创建模拟CurrentUserModule模块之前完成模拟。有没有更好的测试方法?对此我有任何建议。
服务
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="msg"> ERROR MESSAGE OR SUCCESS </div>
<div id="msg2"> ERROR2 MESSAGE OR SUCCESS </div>
测试
import StorageFactoryModule from 'app/common/services/StorageFactory';
class CurrentUser {
constructor(StorageFactory) {
this.storageKey = 'appUser';
this.StorageFactory = StorageFactory;
this.profile = initializeUser.call(this);
function initializeUser() {
var userFromStorage = StorageFactory.get(this.storageKey);
if (userFromStorage != null) {
return userFromStorage;
} else {
// return default user
}
}
}
// more methods, that are removed for brevity
}
CurrentUser.$inject = ['StorageFactory'];
export default angular.module('CurrentUserModule', [StorageFactoryModule.name])
.service('CurrentUser', CurrentUser);
答案 0 :(得分:1)
我设法找到了一种更好的方法,如下所示。我最初是以错误的方式做事(现在觉得很愚蠢)。我没有创建一个模拟模块,而是创建了一个覆盖原始模块的真实模块,这就是它影响所有测试的原因。现在,我正在创建一个模拟模块并使用$ provide来覆盖StorageFactory,这将仅影响当前套件。
beforeEach(function () {
angular.mock.module('StorageFactoryModule');
module(function($provide) {
$provide.value('StorageFactory', storageFactoryMock);
});
angular.mock.module('CurrentUserModule');
});
编辑:通过创建一个接受用户作为参数的函数并根据传递的用户创建模块,重构我的代码并使其更灵活。
var correctUser = {userid: 'abc', token: 'token'};
var defaultUser = {userid: '', token: ''};
function createStorageFactoryMock(userInStorage) {
return {
get: function () {
return userInStorage;
},
put: function (key, newUser) {
userInStorage = newUser;
},
remove: function () {
userInStorage = undefined;
}
}
}
function CreateUserModule(user = correctUser) {
angular.mock.module('StorageFactoryModule');
module(function ($provide) {
$provide.value('StorageFactory', createStorageFactoryMock(user));
});
angular.mock.module('CurrentUserModule');
}
现在在我的测试中,我可以针对不同的场景模拟不同的模块,并相应地编写我的测试。欢迎任何反馈。
it('should Initialize User from storageFactory if already exists in storage', function () {
CreateUserModule();
inject(function (CurrentUser) {
expect(CurrentUser.profile).toEqual(correctUser);
});
});
it('should Initialize default user if user not present in storage', function () {
CreateUserModule(null);
inject(function (CurrentUser) {
expect(CurrentUser.profile).toEqual(defaultUser);
});
});