【发布时间】:2016-06-30 18:23:52
【问题描述】:
我现在有一个项目,我们需要暂时模拟后端服务器,并且我们在应用程序 .run 功能上使用 $httpBackend。我需要对包含$httpBackend 的服务进行单元测试,因为我们将对我们将覆盖的服务器进行大量模拟调用。所以现在这就是我所拥有的。作为我的问题的前言,当我从一个简单页面上的控制器调用 mockDataService.getWorkflowTask 时,当前设置有效。
我的服务器更换服务:
angular.module('app').run(function ($httpBackend, $resource, FakeBackendService) {
// TODO: add all necessary http intercepts.
$httpBackend.whenGET('JSON file').respond(function (method, url, data) {
var request = new XMLHttpRequest();
request.open('GET', url, false);
request.send(null);
return [request.status, request.response, {}];
});
$httpBackend.whenGET(/.*/).respond(function (method, url, data) {
return [200, FakeBackendService.getWorkflowTasks(), {}];
});
});
这里是FakeBackendService的服务:
(function () {
'use strict';
var injectParams = [];
function service(lodash) {
var vm = this;
var ret = {
getWorkflowTasks: getWorkflowTasks
};
function getWorkflowTasks() {
if (vm.workflowtasks.length < 1) {
vm.workflowtasks = loadWorkflowTasks("Some JSON file");
}
return vm.workflowtasks;
};
function loadWorkflowTasks(file) {
var workflowTasks = [];
var request = new XMLHttpRequest();
request.open("GET", file, false);
request.send(null);
if (request.status == 200) {
workflowTasks = angular.fromJson(request.response);
}
return workflowTasks;
};
function init() {
vm.workflowtasks = [];
}
init();
return ret;
}
service.$inject = injectParams;
angular.module('mock.FakeBackendService', []).service('FakeBackendService', service);
})();
所以这是当前后端服务器替换模拟。以下是我的数据处理服务,其中包含对$http.get(blah blah blah) 的调用。
(function () {
'use strict';
var injectParams = ['$http', '$q', 'mockConfigService', '$httpBackend'];
function factory($http, $q, configService, $httpBackend) {
var vm = this;
var factory = {
getWorkflowTask: getWorkflowTask
};
function getWorkflowTask(str) {
return getResource(str);
}
function init() {
// Get the URL we will be using to get data from
vm.dataServiceURL = configService.getDataServiceURL();
}
function getResource(baseResource) {
var resource = vm.dataServiceURL + baseResource;
return $http.get(resource).then(function (response) {
if (typeof response.data == 'object') {
// Got valid response
return $q.resolve(response.data);
}
else {
// Invalid response
return $q.reject(response.data);
}
}, function (response) {
// Something went wrong
return $q.reject(response.data);
});
}
init();
return factory;
};
factory.$inject = injectParams;
angular.module('mock.dataService', []).factory('mockDataService', factory);
}());
现在是 Jasmine-Karma 单元测试。
describe("HTTP Backend Mock testing", function () {
beforeEach(angular.mock.module("app"));
beforeEach(angular.mock.module("mock.FakeBackendService"));
beforeEach(angular.mock.module("mock.configService"));
beforeEach(angular.mock.module("mock.dataService"));
it("Get the workflow task", angular.mock.inject(function (mockDataService) {
var valid = "";
var promise = mockDataService.getWorkflowTask('http://localhost/foo');
promise.then(function (response) {
valid = "Success";
}, function (response) {
valid = "Failure";
});
expect(valid).toBe("Success");
}));
});
现在回答问题。所以,我首先要说我是 AngularJS 世界的新手,对 Jasmine 更是如此。无论如何,当我调试单元测试时,我发现承诺的状态仍然是 0,我总是期望“成功”告诉我我永远不会解决(希望我使用正确的术语)来自 @987654331 的承诺@服务在mockDataService。我已经尝试过使用它,并试图看看是否有人以前做过这种事情。我发现了很多在测试中模拟 $httpBackend 的例子,但没有一个像我正在尝试的那样。任何想法或建议都会很棒。谢谢。
EDIT 得到了一个稍微可行的解决方案
所以我决定绕过run() 服务并在expectGET().respond() 中执行相同的响应。
describe("HTTP Backend Mock testing", function () {
beforeEach(angular.mock.module("app"));
beforeEach(angular.mock.module("mock.FakeBackendService"));
beforeEach(angular.mock.module("mock.configService"));
beforeEach(angular.mock.module("mock.dataService"));
it("Get the workflow task", angular.mock.inject(function (mockDataService, $httpBackend, FakeBackendService) {
var valid = "";
$httpBackend.expectGET('http://server:80/api/foo').respond(200, FakeBackendService.getWorkflowTasks());
var promise = mockDataService.getWorkflowTask('foo');
promise.then(function (response) {
valid = "Success";
}, function (response) {
valid = "Failure";
});
$httpBackend.flush();
expect(valid).toBe("Success");
}));
});
这解决了我使用run() 的测试问题,因为目标是验证1) 正则表达式匹配调用正确的FakeBackendService 和2) FakeBackendService 返回正确的文件并实际加载它。我想我可以通过模仿expectGET 中的相同正则表达式来做到这一点。但是,我会稍微开放一下,看看是否有人知道如何让run() 工作。
【问题讨论】:
标签: angularjs unit-testing jasmine karma-jasmine