Expecting URL with parameters with $httpBackend

6,522 views
Skip to first unread message

Witold Szczerba

unread,
Mar 10, 2012, 6:47:56 PM3/10/12
to ang...@googlegroups.com
Hi there,
I have just created an 'executable spec(*1)' :) for my TableModel like this:

https://gist.github.com/2013912

It works fine against my implementation, I am however concerned that
it works "by accident". I am using $resource service and I have no
idea where does the order of parameters comes from. For example:
var criteria = {page:1, orderBy:'age:asc', name: 'smith'};
SomeResource.query(criteria);
produces query:
'some/url?name=smith&orderBy=age:asc&page=1'

Do you have any idea how to make proper expectations for the above in
test? The order of parameters does not matter for server, maybe the
$httpBackend mock would have to support parameters as an object?

By the way: if you find some malpractice in that test, let me know,
because (maybe) I will use it for my next blog entry.
_____________
(*1) slide #19
https://docs.google.com/present/view?id=d449gch_277fc6wwc9s
_____________

Thanks,
Witold Szczerba

Vojta Jína

unread,
Mar 10, 2012, 9:45:27 PM3/10/12
to ang...@googlegroups.com
$httpBackend mock accepts regexps as well:
$httpBackend.expectGET(/someregexp/).respond();

So try something like this:

function unorderedArgs(url, params) {
  return {
    test: function(requestedUrl) {
      // check the base url (i.g. /some/url)
      if (requestedUrl.indexOf(url) !== 0) return false;
      var urlEncodedArgs = requestedUrl.substr(url.length);
      return angular.equals(params, parseUrlEncoded(urlEncodedArgs));
    }
  };
}


And then:
$httpBackend.expectGET(unorderedArgs('some/url', {name: 'smith', orderBy: 'age:asc', page: 1}).respond();


V,

Witold Szczerba

unread,
Mar 11, 2012, 8:40:04 PM3/11/12
to ang...@googlegroups.com
Oh my, it looks like a implementation-detail trick to me. If expectGET
officially accepts a regexp and then, instead of providing a proper
regexp, one is providing an object with a 'test' function, and it
works - then it seems like a trick. I mean it can break down once an
expected regexp will be used in different way than using it's 'test'
function.

Another thing is, that even though a duck-type regexp substitute is
used, the provided example shows:

return angular.equals(params, parseUrlEncoded(urlEncodedArgs));

I suppose the 'parseUrlEncoded' function is not accessible from
outside of AngularJS code base, and even if it actually is accessible,
then it is, again, the implementation detail that $resource is using
that function and not something else to produce a set of parameters in
URL string.

Regards,
Witold Szczerba

> --
> 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/-/ziG17cE0zOAJ.
> 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.

Vojta Jína

unread,
Mar 12, 2012, 12:49:51 AM3/12/12
to ang...@googlegroups.com
Yep, it's kinda trick, that relies on implementation detail. But it works :-D

I actually think, we might allow passing a function as well. (string / regexp / function)

parseUrlEncoded() does not exist - you have to write it ;-) I didn't write the code for it, as the point of the example was something else.
You can copy paste parseKeyValue from Angular (it's not public api, it's not exposed):

V.

Reply all
Reply to author
Forward
0 new messages