Angularjs 如何在Angular中测试返回$http请求的服务函数
我有一个发出$http请求的简单服务Angularjs 如何在Angular中测试返回$http请求的服务函数,angularjs,jasmine,Angularjs,Jasmine,我有一个发出$http请求的简单服务 angular.module('rootApp') .factory('projectService', ['$http', function ($http) { return { getProject: getProject, getProjects: getProjects, }; function getProject(id) {
angular.module('rootApp')
.factory('projectService', ['$http', function ($http) {
return {
getProject: getProject,
getProjects: getProjects,
};
function getProject(id) {
return $http.get('/projects.json/', { 'params': { 'id': id }});
}
}]);
我想知道如何简单而干净地测试这个?以下是我到目前为止的测试结果
describe("Root App", function () {
var mockGetProjectResponse = null,
$httpBackend = null;
beforeEach(module('rootApp'));
beforeEach(inject(function (_$httpBackend_, projectService) {
$httpBackend = _$httpBackend_;
$httpBackend.when('GET', '/projects.json/?id=1').response(mockGetProjectResponse);
}));
describe("should get projects successfully", inject(function (projectService) {
it("should return project", function () {
// I essentially want to do something like this (I know this isn't the right format).. but:
//expect(projectService.getProject(1)).toBe(mockGetProjectResponse);
});
}));
我希望避免在测试中显式调用$http.get(…),而是坚持调用服务函数,即projectService.getProject(1)。我所坚持的是不能做这样的事情:
projectService.getProject(1)
.success(function (data) {
expect(data).toBe(whatever);
})
.error(function () {
});
因为没有空间调用$httpBackend.flush()
任何帮助都将不胜感激。谢谢。测试承诺(包括
$http
)的常用方法是
一个很好的替代方案是消除间谍样板代码的需要
这说明了两者
通常,用户可能希望使调用$http
的方法尽可能精简,并将其存根,因此可能根本不需要模拟$httpBackend
在当前的示例中,spec实际上什么都不测试,如果代码覆盖率本身不是目的,那么可以省略它并将其留给e2e测试。测试承诺有点过分。但是这个不应该被测试。显然,您在这里测试了$http本身,这是由Angular框架以前完成的。这个问题的规格简化了吗?@estus,是的,这个问题的规格简化了,除了显示的功能外,服务中只有一个类似的功能。是的,很好。仅仅测试$http.get本身可能就可以了,因为这就是所有发生的事情,我似乎无法让它工作。最后,我只是将函数调用分配给一个变量,然后刷新httpBackend,然后将$$state.value.data与预期结果进行比较。我已经用工作示例更新了答案。我不认为$$被禁止,但它可以(有时也)改变而不通知,因此在测试中使用是不可接受的,因为它首先需要测试。
it("should return project", function () {
var resolve = jasmine.createSpy('resolve');
projectService.getProject(1).then(resolve);
expect(resolve).toHaveBeenCalledWith(mockGetProjectResponse);
});