$resource vs $http and unit testing

6,047 views
Skip to first unread message

wapa...@gmail.com

unread,
Jun 14, 2012, 9:09:44 AM6/14/12
to ang...@googlegroups.com
Hi:

I had a working example of CRUD using $resource that is available here: https://github.com/neosavvy/dropwizard-js-user-management

As you can see by looking at this controller: https://github.com/neosavvy/dropwizard-js-user-management/blob/master/commons-user-client/src/main/resources/angular/js/controller1.0.js I am using $resource to interact with my service. Now I am working on unit testing this bad-boy. I noticed that i consistently get this error when trying to instantiate the unit test and I have now learned that this is because angular-mocks.js doesn't include a mock version of $resource. If that is the case is it a good idea to avoid $resource and use instead $http for all REST-ful service calls? I just want to make sure I am using the best approach for the future before I get too far off track. 

If you can pass me an example of a CRUD-style controller with a unit test I'd appreciate that as well to see if I am doing this all right. 

Error is below followed by some sample code I am attempting to use for the unit test.

myController function UserController.should have a hello string with a value of "hello" failed (4.00 ms): Error: Error: Unknown provider: $resourceProvider <- $resource
Error: Expected undefined to be 'hello'.
            Error: Unknown provider: $resourceProvider <- $resource
            at Error (unknown source)
            at _/main/resources/admin/js/lib/angular.js:2627:23
            at Object.getService [as get] (_/main/resources/admin/js/lib/angular.js:2755:53)
            at _/main/resources/admin/js/lib/angular.js:2632:53
            at getService (_/main/resources/admin/js/lib/angular.js:2755:53)
            at invoke (_/main/resources/admin/js/lib/angular.js:2773:31)
            at Object.instantiate (_/main/resources/admin/js/lib/angular.js:2805:33)
            at _/main/resources/admin/js/lib/angular.js:4619:34
            at [object Object].<anonymous> (unit/controllersSpec.js:19:30)
            at Object.invoke (_/main/resources/admin/js/lib/angular.js:2795:40)
            Error: Declaration Location
            at lib/angular/angular-mocks.js:1696:21
            at [object Object].<anonymous> (unit/controllersSpec.js:13:20)
            at [object Object].<anonymous> (unit/controllersSpec.js:9:5)
      
            Error: Expected undefined to be 'hello'.
            at [object Object].<anonymous> (unit/controllersSpec.js:23:33)


Unit test:

'use strict';

/* jasmine specs for controllers go here */

describe('myController function', function() {
    describe('UserController', function(){
        var userController;
        var scope, userController, $httpBackend;

        beforeEach(inject(function($rootScope, $controller, _$httpBackend_) {

            scope = $rootScope.$new();
            $httpBackend = _$httpBackend_;
            $httpBackend.expectGET('phones/phones.json').
                respond([{name: 'Nexus S'}, {name: 'Motorola DROID'}]);
            userController = $controller(UserController, {$scope: scope});
        }));

        it('should have a hello string with a value of "hello"', function() {
            expect(scope.hello).toBe('hello');
        });
    });

});

Vojta Jína

unread,
Jun 26, 2012, 1:01:20 AM6/26/12
to ang...@googlegroups.com
$resource is just a higher abstraction on the top of $http, so if $resource fits your needs, use it.

Even if you are using $resource, you can use $httpBackend mock for testing it.
$resource talks to $http, $http talks to $httpBackend (which you mock out during unit test).


V.

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To view this discussion on the web visit https://groups.google.com/d/msg/angular/-/6IRdMld5Sh8J.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/angular?hl=en.

edgardo....@gmail.com

unread,
Jul 25, 2012, 3:12:09 PM7/25/12
to ang...@googlegroups.com
you can try to use $httpBackend.flush();
like in the tutorial http://docs.angularjs.org/tutorial/step_05

akro...@gmail.com

unread,
Jan 9, 2013, 11:13:41 AM1/9/13
to ang...@googlegroups.com
Yes but how is the question? If I have a controller that expects $resource how do I satisfy that parameter when creating my controller?

ctrl = $controller(PermissionsCtrl, {$scope: scope, $cookies: cookies, $resource: <what goes here?>});

I've already $httpBackend:

$httpBackend = _$httpBackend_;

And told it to expect the appropriate calls. I am still getting the same unknown provider error.

Pawel Kozlowski

unread,
Jan 9, 2013, 1:43:57 PM1/9/13
to ang...@googlegroups.com
Hi!

On Wed, Jan 9, 2013 at 5:13 PM, <akro...@gmail.com> wrote:
> ctrl = $controller(PermissionsCtrl, {$scope: scope, $cookies: cookies,
> $resource: <what goes here?>});

It is more like:

ctrl = $controller(PermissionsCtrl, {$scope: scope, $cookies: cookies});

You shouldn't try to inject $resource (this is used to define resource
objects) but rather an already generated resource. So I would expect
your controller be defined something like:

PermissionsCtrl($scope, $cookies, MyResource)

where MyResource was already defined with:

.factory('MyResource', function($resource){
return $resource(...);
});

Hope that it helps a bit, if not send a plunk with code snippet
(plunker has a template to bootstrap a plunk for AngularJS test with
Jasmine).

Cheers,
Pawel


--
Question? Send a fiddle
(http://jsfiddle.net/pkozlowski_opensource/Q2NpJ/) or a plunk
(http://plnkr.co/)
Need help with jsFiddle? Check this:
http://pkozlowskios.wordpress.com/2012/08/12/using-jsfiddle-with-angularjs/

Looking for UI widget library for AngularJS? Here you go:
http://angular-ui.github.com/

akro...@gmail.com

unread,
Jan 9, 2013, 3:25:48 PM1/9/13
to ang...@googlegroups.com
hm maybe I built my controller wrong then. my control is defined PermissionsCtrl($scope, $cookies, $resource). Is this bad practice?

Pawel Kozlowski

unread,
Jan 9, 2013, 3:27:41 PM1/9/13
to ang...@googlegroups.com
Hi!

On Wed, Jan 9, 2013 at 9:25 PM, <akro...@gmail.com> wrote:
> hm maybe I built my controller wrong then. my control is defined
> PermissionsCtrl($scope, $cookies, $resource). Is this bad practice?

Yes, I would say it is a bad practice since you won't be able to
inject you newly-defined resource and thus it will be accessible in
your controller only.

akro...@gmail.com

unread,
Jan 9, 2013, 8:27:49 PM1/9/13
to ang...@googlegroups.com
Why wouldn't I be able to inject it similar to $cookies or $scope? With both of those I make a mock object in my test set up and then inject that into my controller. That's exactly the same thing I want to do with $resource.

akro...@gmail.com

unread,
Jan 9, 2013, 8:31:30 PM1/9/13
to ang...@googlegroups.com, akro...@gmail.com
Hm actually I guess I see that it isn't exactly the same. I do want the actual service to be available not a mock. So what is the right way to pass this service to my controller. In every example I've seen service are passed as parameters to the controllers.

akro...@gmail.com

unread,
Jan 9, 2013, 8:43:15 PM1/9/13
to ang...@googlegroups.com, akro...@gmail.com
Heres' a plunk maybe that'll make it easer to discuss: http://plnkr.co/edit/76cRBwWjUWBXIwR9r5JL
Reply all
Reply to author
Forward
0 new messages