How to test a service function in Angular that returns an $http request

旧时模样 提交于 2020-03-02 15:41:48

问题


I have a simple service that makes an $http request

angular.module('rootApp')
    .factory('projectService', ['$http', function ($http) {

        return {
            getProject: getProject,
            getProjects: getProjects,
        };

        function getProject(id) {
            return $http.get('/projects.json/', { 'params': { 'id': id }});
        }
    }]);

I'm wondering how can I test this simply and cleanly? Here's what I have so far in my test.

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

    });
}));

I want to avoid explicitly calling $http.get(...) in my test, and rather stick to calling the service function, i.e. projectService.getProject(1). What I'm stuck on is not being able to do something like this:

projectService.getProject(1)
    .success(function (data) {
                expect(data).toBe(whatever);
            })
            .error(function () {

            });

Since there's 'no room' to call $httpBackend.flush();

Any help would be much appreciated. Thanks.


回答1:


The usual recipe for testing promises (including $http) is

it("should return project", function () {
    var resolve = jasmine.createSpy('resolve');
    projectService.getProject(1).then(resolve);
    expect(resolve).toHaveBeenCalledWith(mockGetProjectResponse);
});

A good alternative is jasmine-promise-matchers which eliminates the need for spy boilerplate code.

Here's a plunker that demonstrates both of them.

Generally the one may want to keep the methods that make $http calls as thin as possible and stub them instead, so mocking $httpBackend may not be required at all.

In current example the spec tests literally nothing and can be omitted and left to e2e tests if the code coverage isn't an end in itself.



来源:https://stackoverflow.com/questions/33589854/how-to-test-a-service-function-in-angular-that-returns-an-http-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!