Search code examples
angularjsjasmineangular-resource

AngularJS weird behaviour with $resource and $httpBackend


I have following AngularJS resource exposed as a service

 myServices.factory('Service1', ['$resource',
    function ($resource) {

        var Registrations = $resource('/api/v1/registration/:id');

        return {
            getForTcn: function(tcn) {
                return Registrations.query({ tcn: tcn, state: 'Active' }).$promise;
            }

        };
    } ]);

And I have a Jasmine test which fails below

beforeEach(inject(function (_$httpBackend_, Service1) {
    $httpBackend = _$httpBackend_;
    service = Service1;

    $httpBackend.when('GET', /^\/api\/v1\/registration\?.*/).respond([]);
}));afterEach(function () {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
});

With above setup below assertion fails

it('should have correct http GET request', function () {
    Service.getForTcn('1234');
    $httpBackend.expectGET('/api/v1/registration?tcn=1234&State=Active');
    $httpBackend.flush();
});

If I swap the places of the parameters in the service function and in the assertion the test passes.

getForTcn: function(tcn) {
                return Registrations.query({ state: 'Active', tcn: tcn }).$promise;
            }
$httpBackend.expectGET('/api/v1/registration?state=Active&tcn=1234');

Any idea what's going on here? I haven't tried if the version that's failing actually works when executed outside test but has anyone seen similar behaviour?
Thanks


Solution

  • The problem is the query arguments are arranged alphabetically so if you had foo as an argument then your assertion would be:

    $httpBackend.expectGET('/api/v1/registration?foo=1234&state=Active');
    

    and this would pass. Conversely if the argument was zoo then the assertion would be:

    $httpBackend.expectGET('/api/v1/registration?state=Active&zoo=1234');
    

    which is why you have to put tcn after the state argument as you indicate in your question.