AngularJS单元测试——多个模拟和提供程序
AngularJS Unit Testing - multiple mocks and providers
我开始为我的Angular应用做单元测试,我有一些关于如何构建测试文件夹的问题。我基本上使用了约曼角生成器,所以它附带了预配置的Jasmine和Karma。
下面是我要测试的一个场景…
我有一个"PageHeaderDirective"显示用户的姓名和电子邮件(如欢迎消息)以及注销链接。页面头指令的代码是无关紧要的,但我确实需要从后端点击"/user"端点来获取用户的详细信息。下面是UserService的代码,它被注入到PageHeaderDirective:
/**
* @ngdoc function
* @name Common.service.UserService
* @description
* Service to retrieve a {@link User} from the backend.
*/
(function () {
'use strict';
angular.module('Common').service('UserService', UserService);
UserService.$inject = ['User', 'Restangular'];
/**
* User service function.
* @param User The {@link User} provider.
* @param Restangular The restangular provider.
*/
function UserService(User, Restangular) {
var userPromise;
return {
getUser: getUser
};
/**
* Retrieves a {@link User} instance from the /user endpoint.
* @returns A promise to be resolved with a {@link User} instance.
*/
function getUser() {
if(!userPromise) {
userPromise = Restangular.one('user').get().then(function(data) {
return User.factory(data);
});
}
return userPromise;
}
}
})();
这是一个非常简单的测试PageHeaderDirective:
describe('Pageheader Tests', function() {
'use strict';
var scope;
var element;
beforeEach(module('templates'));
beforeEach(module('Common'));
beforeEach(inject(function(_$rootScope_, $compile) {
scope = _$rootScope_.$new();
scope.message = 'Test message';
element = '<ft-page-header message="message" page="home"></ft-page-header>';
element = $compile(element)(scope);
scope.$digest();
}));
it('should render a page header with the logo and username', function() {
expect(element.find('.logo-text').length).toBe(1);
var isolateScope = element.isolateScope();
expect(isolateScope.name).toBe('test');
});
});
现在,正如你可能会告诉,我得到一个未知的提供者错误"未知的提供者:RestangularProvider <- RestangularProvider <- UserService <- pageHeaderDirective",因为我还没有注入到测试。
我读到你可以在每个测试文件中做像beforeEach(function(){ module(function($provide) { $provide.service('UserService', function() { ... }})});
这样的事情,但我真的不想在指令/控制器使用UserService时这样做。我如何将该部分从每个测试文件中分离出来,并将其放入自己的"UserService.mock.js"文件中?如果可能的话,我如何将"UserService.mock.js"注入到我的测试中?
其次,我也注入Restangular到PageHeaderDirective注销用户(Restangular.one('logout').get().then...
)。我如何模拟这个(我从来不想调用API端点)?
最后,如果我正在注入其他提供程序($document, $localStorage, $window),我是否需要将所有这些也注入到测试中?如果有,怎么做?
谢谢!
如果有人想做我所做的(把你的模拟分成不同的文件,这样你就不需要复制粘贴很多东西),这是我发现的。
// /test/mock/UserService.mock.js
(function() {
"use strict";
angular.module('mocks.Common').service('UserService', mock);
mock.$inject = ['$q', 'User'];
function mock($q, User) {
return {
getUser : getUser
};
function getUser() {
return $q.when(User.factory({
firstName: 'test',
email: 'test@gmail.com',
id: 1
}));
}
}
})();
因此,首先,您需要确保创建了模块(在本例中我创建了"mocks.Common")。在一个单独的文件中,我放入这一行:angular.module('mocks.Common', []);
这创建了我的"mock"。常见的"模块。然后,我创建了一个名为"UserService"的模拟,并使用$q返回一个带有一些虚拟数据的承诺。User.factory
部分只是一个工厂功能在我的真正的应用程序从通用模块。
一旦你有了上面模拟的"UserService",确保在测试的设置过程中以正确的顺序注入模块。像这样:
module('app');
module('templates');
module('mocks.Common');
现在,当我的测试运行,PageHeaderDirective将使用模拟的"UserService",而不是真正的一个!
至于我的第二个问题:我还没有真正做过,但我相信我将能够使用$httpBackend来测试任何Restangular功能。
第三,我发现如果你在所有的测试中运行module('appName')
,你应该自动得到任何需要的依赖项。例如,下面是我的整个应用程序的模块定义:
angular.module('app', [
'Common',
'ngAnimate',
'ngCookies',
'ngResource',
'ngRoute',
'ngSanitize',
'ngTouch',
'ngDialog',
'ngStorage',
'lodash',
'smart-table',
'rhombus',
'helpers',
'restangular',
'moment',
'cgBusy',
'duScroll'
])
所以当我做module('app')
时,我在测试中自动获得所有这些依赖项(注意我的应用配置中的"Common"依赖项)。
- 使用Node.js在应用程序引擎上进行本地单元测试
- 用于单元测试的模拟Angular引导程序ui指令
- 如何使用Karma单元测试运行程序捕获console.error
- 使用karma浏览器对AngularJS应用程序进行单元测试
- 使用节点单元编写带有数据库连接/驱动程序的单元测试
- 当使用 Jasmine 对我的 angularJS 应用程序进行单元测试时,$interval是未定义的
- 调度程序未在开玩笑单元测试中注册回调
- 是否应该对 JavaScript 事件处理程序进行单元测试
- 将模拟提供程序注入到角度单元测试中
- 用于单元测试和运行基于浏览器的 Web 应用程序的 Javascript 日志记录设置
- Spotify应用程序的推荐单元测试框架/测试运行程序
- 单元测试使用$translatePartialLoaderProvider的AngularJS应用程序
- 如何使用qunit在ember-cli应用程序中对Routes进行单元测试
- 单元测试提供程序配置中的$urlRouterProvider.otherwise
- Ext.JS 4.2.1使用Jasmine进行单元测试-未定义应用程序
- 在大型web应用程序中处理JavaScript(可重用性、捆绑、单元测试等)
- 单元测试混合角度/反应应用程序
- 如何对一个主要负责重定向到应用程序外部页面的Angular服务进行单元测试
- Java web应用程序的项目结构,javascript提供依赖管理、单元测试、ci以及对maven和eclipse的支
- 如何在AngularAMD应用程序单元测试中模拟服务