user5080246
user5080246

Reputation: 193

AngularJS $resource service mocking, the right way

I am confused about the way AngularJS $resource service is supposed to be mokced for testing. I found two ways to use $httpBackend service for it. One way (taken from a Pluralsight tutorial):

describe('test', function() {

    beforeEach(module('name'));

    it('text', inject(function($httpBackend) {
        $httpBackend.expectGET("/url");
        // some code
        $httpBackend.flush();
    });
}

An other way (copied from this SO answer):

describe('test', function () {
    var $httpBackend;
    beforeEach(angular.mock.module('name'));

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

    describe('text', function () {
        it('text', inject(function (User) {
            $httpBackend.expectGET('/url')
                .respond([{
                    property: 'test'
                }]);

            // Some code

            $httpBackend.flush();
        }));

    });
});

I don't understand why the first way, uses module directly whereas the second way does angular.mock.module. And then the httpBackend service is injected so differently. The second way is so much more verbose. If the first way works, what's the point in all that verbosity of the second way?

Upvotes: 0

Views: 67

Answers (1)

Estus Flask
Estus Flask

Reputation: 222865

There's no right way, there are several different concerns here that should be kept in mind.

module is a shortcut for angular.mock.module. The latter can be used to avoid conflict with CommonJS modules.

The only reason why angular.mock.inject was used there is consistency with angular.mock.module, it can always be safely shortened to inject.

beforeEach(inject(...)) is used if the same services are supposed to be used in multiple specs.

beforeEach(function () { inject(...) }) is verbose version of beforeEach(inject(...)). If there should be something besides inject in beforeEach block, consider splitting it to several beforeEach blocks instead for readability.

$injector.get is just verbose and provides no benefits here in terms of style or features. It does nothing good if the services are variables, but it provides a useful pattern for assigning services in batch to this spec context without enumerating them several times:

beforeEach(inject(function ($injector) {
  var self = this;

  ['$httpBackend', ...].forEach(function (depName) {
    self[depName] = $injector.get(depName);
  });
}));

it(function () {
  var self = this;

  self.$httpBackend...
});

Upvotes: 1

Related Questions