Angularjs 如何在Angular中测试返回$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) {

我有一个发出$http请求的简单服务

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);
});