Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make $httpBackend insensitive to the order of URL query parameters?

I am using the Angular.js $httpBackend to test some services that wrap $http calls (this is in ngMock, not ngMockE2E).

It seems that things like expect and when are sensitive to the order of URL query parameters. E.g. if I do $httpBackend.when('POST','/apiCall?X=1&Y=2').respond(/* ... */) or $httpBackend.expectPOST('/apiCall?X=1&Y=2'), I get URL mismatches if I have Y=2&X=1 in the URL instead of X=1&Y=2.

I want to write my tests in such a way that the service being tested will be free to change the order of URL query string parameters without breaking the tests. I haven't been able to find anything to solve this in the $httpBackend documentation. What's the right way to do this?

like image 814
Eugene Osovetsky Avatar asked Mar 12 '14 20:03

Eugene Osovetsky


2 Answers

angular will sort the keys of the params object used in conjunction with $http.

$http({
    url:"/myurl",
    method:"GET",
    params:{
       Y:1
       X:2
    }}); 

Angular will do the following effectively: Object.keys(myParams).sort() and append the keys in that order. which ends up being '/myurl?X=2&Y=1'

I would suggest consistently using query parameters not directly in the url, but instead in the parameter params: that angular will then process.

Another solution would be to use Regular Expressions in your tests, something like

$httpBackend.expectPOST(/\/myurl\?((X|Y)=\d{1,}&?){2}/) regexper

The fact that you can use RegExp's is really hard to spot since the documentation redesign, as the colors do not blend.

like image 180
calebboyd Avatar answered Oct 11 '22 05:10

calebboyd


you can use the $httpParamSerializer service to achieve this:

$httpParamSerializer({ param: 1, param2: 2 });

This will return you a matching stringified querystring matching angulars $http service with params.

like image 22
raygerrard Avatar answered Oct 11 '22 06:10

raygerrard