Testing $resource services in AngularJS

angular-resource, angularjs

Solution

You can mock the requests made by ngResource like this:

describe('User', function () {
    var mockUserResource, $httpBackend;
    beforeEach(angular.mock.module('myApp'));

    beforeEach(function () {
        angular.mock.inject(function ($injector) {
            $httpBackend = $injector.get('$httpBackend');
            mockUserResource = $injector.get('User');
        })
    });

    describe('getUser', function () {
        it('should call getUser with username', inject(function (User) {
            $httpBackend.expectGET('/api/index.php/users/test')
                .respond([{
                username: 'test'
            }]);

            var result = mockUserResource.getUser('test');

            $httpBackend.flush();

            expect(result[0].username).toEqual('test');
        }));

    });
});

Demo

Problem

I am trying to begin writing unit tests for my angular application and hit a stopping block pretty quick as I am unsure of how exactly to mock my service in a testable way. Is there a way to mock the REST call otherwise it would seem like I need to mirror everything within my service in my tests which doesn't seem right to me, but I am rather new to test writing so maybe this is how it is supposed to be accomplished. Any help would be greatly appreciated. My service is as follows: ``` angular.module('resources.users', ['ngResource']) .factory('User', function($resource) { var resource = $resource('/api/index.php/users/:username', {}, { 'update': {method: 'PUT'} }); resource.getUser = function(username, successCb) { return resource.query({username: username}, successCb); }; return resource; }); ``` My test consists thus far of: ``` describe('User', function() { var mockUserResource; beforeEach(module('resources.users')); beforeEach(function() { mockUserResource = sinon.stub({ getUser: function(username) { mockUserResource.query({username: username}); }, query: function() {} }); module(function($provide) { $provide.value('User', mockUserResource); }) }); describe('getUser', function() { it('should call getUser with username', inject(function(User) { User.getUser('test'); expect(mockUserResource.query.args[0][0]).toEqual({username: 'test'}); })); }) }); ```

Original source