【发布时间】:2016-02-20 01:24:59
【问题描述】:
要求
- 基于 Angular 的 REST 客户端组件
- 必须在私有 API 和服务之间进行交互
- Karma/Jasmine 测试不引导应用程序模块
当前的困境
我们不想引导整个应用程序进行单元测试(使用 module() 或 angular.mock.module())。尽管 Angular 的组件注册是一个有用的功能,但它对于企业级应用程序来说似乎是不可持续的。我发现的所有示例都是这样做的,但是根据我们当前的业务目标,我需要在不引导应用程序模块的情况下这样做。
到目前为止,我已经成功注入了 $resource 和 $httpBackend 并且它们都可以正常工作。我可以为 $httpBackend 对象分配响应行为,并且可以将 $resource 注入测试套件中的 restClient 工厂。但是,当我尝试运行它时,它们似乎并不知道彼此,因此客户端实际上正在发送调用(不受欢迎的#1),让 $httpBackend 对象等待着非常好的期望并且没有任何东西可以刷新(#2) .
请帮忙
您能否指出我缺少的配置错误,以便在不调用 module() 的情况下使这两个部分协同工作?
测试错误
Error: No pending request to flush !
at Function.$httpBackend.flush (node_modules/angular-mocks/angular-mocks.js:1544:34)
at Object.<anonymous> (/var/folders/8h/lqyqq1ks6vv8z5mpsxjqn5sw0000gn/T/89bece8e9480f44013f53b3f1b05b4ba.browserify:855:22 <- src/app/services/restClient_test.js:24:0)
Error: Unsatisfied requests: GET https://ourlink.nl
at Function.$httpBackend.verifyNoOutstandingExpectation (node_modules/angular-mocks/angular-mocks.js:1577:13)
at Object.<anonymous> (/var/folders/8h/lqyqq1ks6vv8z5mpsxjqn5sw0000gn/T/89bece8e9480f44013f53b3f1b05b4ba.browserify:847:22 <-
来自失败的 restClient XHR 的浏览器错误
XMLHttpRequest cannot load undefinedhttps://oursite.nl?userId=UserZ. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
restClient.js:
function restClient ($resource, baseUrl) {
'use strict';
return {
get: get
};
function get (route, options) {
var self = this;
var payload = $resource(self.baseUrl + route, options).get(options.routeParams);
return payload;
}
}
module.exports = restClient;
restClient_test.js:
describe('restClient', function () {
var client, $httpBackend;
beforeEach(inject(function(_$httpBackend_) {
$httpBackend = _$httpBackend_;
}));
beforeEach(function () {
var $injector = angular.injector(['ng', 'ngResource']);
this.client = require('./restClient.js');
client = this.client($injector.get('$resource'));
});
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('sends a get request', function () {
$httpBackend.expectGET('https://oursite.nl')
.respond('200', {userId: 'UserZ'}, {token: '1234'});
client.get('https://oursite.nl', {userId: 'UserZ'});
$httpBackend.flush();
});
});
【问题讨论】:
-
你认为它是如何工作的?您继续使用“注入”,但不想使用“模块”。因此,您的 $injector 与 ngMock 使用的不同。 ngMock 是框架的一部分(非常有用且经过深思熟虑的部分),您应该喜欢它或离开它,就像任何框架一样。
-
我们正在使用 ngMock,这是我们可以访问注入的地方。我不应该需要整个应用程序进行单元测试。最终,这不是我不使用 module() 引导应用程序的决定,但我认为他(我们的架构师)是有道理的。无论如何,这些都是要求。如果你不喜欢它,你不必帮忙。
-
那么你有我的同情,这种决定和重新创建 ngMock 功能的需要不会使测试更容易。对我来说它看起来像 XY 问题,这可能是由于缺乏模块化造成的(类似于this case)。当模块的设计考虑到测试时,无需引导整个应用程序。
-
我不确定我们是否正在重新创建功能。我们只是想要少一点功能。一个代码单元应该可以作为一个单元进行测试。这就是我们所追求的。现在我们让它工作了,它实际上非常好。
-
您可能经常会偶然发现过度的“一个组件,一个模块”模块化,例如'foo.bar.bazController'。在生产代码中可能有点冗长,因为 JS 缺少命名空间功能,但解耦单元测试正是它的用途。
标签: javascript angularjs rest jasmine karma-runner