6

I'm trying to test a controller in my Angular framework:

.controller('UserCtrl', ['$scope', '$location', 'User', 'Config',
    function ($scope, $location, User, Config) {
       ...
    }])

This controller depends on a couple of Services that require the $http object to make server calls:

.factory('User', ['$http', function ($http) {
    var data = {};

    return {
        query: function(oper, putdata, callback){
            if(oper == 'get'){
            $http.get(getUrl("user",null)).success(function(data2) {
                console.log(data2);

                callback(data2);
                data.userinfo = data2;
            });
            },

        userinfo: data
    };
}])

But when I try bootstrapping the controller I can't get httpBackend to work:

describe('UserCtrl', function(){

    var ctrlScope, ctrl, $httpBackend, controllerService;

    beforeEach(
        inject(function($httpBackend, $http, $rootScope, $controller, User, Config) {
            _User = User;
            _Config = Config;
            spyOn(User, 'getUserInfo').andCallThrough();
            //spyOn(User, 'query').andCallThrough();

            ctrlScope = $rootScope.$new();
            controllerService = $controller;
            httpMock = $httpBackend;

        })
    );

    it('should create setup userinfo object ', function() {
        httpMock.expectGET("/user/default/details").
            respond({somejson});

        ctrl = controllerService('UserCtrl', {$scope: ctrlScope, $location: location, User: _User, Config: _Config});
        expect(_User.getUserInfo).toHaveBeenCalled();
        httpMock.flush();
        expect(ctrlScope.userinfo.length).toBe(1);

    });
});

All I ever get is:

Error: No pending request to flush !

so is it possible to use httpBackend with a service that you have called from a controller you are testing?

1
  • Where is getUserInfo defined? It seems like your method is still called 'query'? Commented Jul 11, 2013 at 3:14

1 Answer 1

1

Is there a reason you want to specifically test for a GET request? This is an implementation detail of your User service.

Regardless of whether your function is called query() or getUserInfo(), I suspect all that you really want to know is that the function was called on your User service. It's up to the User service to have it's own set of tests that will test that a GET request was made to /user/defaults/details.

The reasoning behind this is that you don't want unrelated unit tests to break when you change the implementation of your User service. What happens when your API changes to /user/query? Your UserCtrl tests should not break, nor should any other controller that's using User service. If your UserCtrl is calling getUserInfo() on User service, it's doing the right thing as far as you're concerned. Your User service unit tests will break and once you fix them to point to your new URL, everything is back in order.

Sign up to request clarification or add additional context in comments.

1 Comment

I was about to ask the same think, struggling for hours trying to test a similar scenario. Thanks for the reply, it's clarified a lot of things

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.