$httpBackend with request with query param
Asked Answered
M

3

11
$httpBackend.whenGET('/restpath/api/v1/books')
.respond({// some data}); 

I get the following error

Error: Unexpected request: GET /restpath/api/v1/books
 Expected GET /restpath/api/v1/books?limit=10&start=1

For the expectGET I have the following , and this creates dynamic query string. mostly the 'start' parameter, and the whenGET part, I am trying to server a dynamic content depending on the 'start'

$httpBackend.expectGET('/restpath/api/v1/books?limit=10&start=1'); // the actual service goes here , which does the $http service. we don't care $httpBackend.flush();

Misgive answered 14/8, 2015 at 6:52 Comment(3)
How is the get called in the code you are testing?Douglas
updated the expectGet , is that what you are looking for ?Misgive
It looks like you expect the get to have parameters, but it doesn't. Make sure that your test is set up in the way that when the application code calls the get, it does so with the expected parameters, ie. {limit: 10, start: 1}Douglas
Y
23

(for angular apps with versions lower than v1.5.0-build.4371 )

If you dont care about the parameters after your '?' you can do this :

$httpBackend.expectGET(/.*?restpath\/api\/v1\/books?.*/g).respond(200, '{}');

if you care about the first param do this :

$httpBackend.expectGET(/.*?restpath\/api\/v1\/books?limit=10.*/g).respond(200, '{}');

if you care about them all do this :

$httpBackend.expectGET("/restpath/api/v1/books?limit=10&start=1").respond(200, '{}');
Yawning answered 14/8, 2015 at 9:48 Comment(1)
+1 Adds point to the questions, yes, but I care about the param, and basing on the param I will be responding to the request ( httpbackend )Misgive
M
13

EDIT

As of v1.5.0-build.4371 the docs state that the respond callback accepts a params argument.

By default, query parameters on request URLs are parsed into the params object. So a request URL of /list?q=searchstr&orderby=-name would set params to be {q: 'searchstr', orderby: '-name'}

So for '/restpath/api/v1/books?limit=10&start=1' you will get:

$httpBackend
   .whenGET('/restpath/api/v1/books?limit=10&start=1')
   .respond(function(method, url, data, headers, params) {

    // params will be {
    //   limit: 10,
    //   start: 1
    // }

   });

PREVIOUS

  1. You use

    • .expectGET() if you want to $httpBackend to throw an exception on mismatch.
    • .whenGET() in the other cases.
  2. The docs state that .respond() can accept either an Array or a callback function, with the signature: function(method, url, data, headers) {};

Now that we know how to access the request url, in order to serve a dynamic content, we can simply parse the url we receive in the .respond() callback using a helper function such as the one posted by Andy E in this question:

// inspired by Andy E
// @https://stackoverflow.com/users/94197/andy-e

function matchParams(query) {
   var match;
   var params = {};

   // replace addition symbol with a space
   var pl = /\+/g;

   // delimit params
   var search = /([^&=]+)=?([^&]*)/g;


   var decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); };

   while (match = search.exec(query))
     params[decode(match[1])] = decode(match[2]);

   return params;
}

With this helper in our scope, we can know build a dynamic response, such as:

// we use a regex to be able to still respond to 
// dynamic parameters in your request
var urlRegex = /\/restpath\/api\/v1\/books\?limit=(\d+)&start=(\d+)/;

$httpBackend
   .whenGET(urlRegex)
   .respond(function(method, url){

      // send only the url parameters to the helper
      var params = matchParams(url.split('?')[1]);

      // params is now an object containing
      // {limit: 10, start:1}
      // so do whatever you want with it.
      var dynamicData = getMockData(params.start);


      // don't forget to return.
      return [200, dynamicData];
   });

mySuperFactory.method().then(...);

// now resolve the Promise by flushing.
$httpBackend.flush();

And voila! You can serve dynamic mock data to your tests.

Malaria answered 4/11, 2015 at 19:4 Comment(2)
Great. Just remember to JSON.parse the data argument if you need to access some propertiesMolest
He is asking for expectGET to validate the params not whenGET to utilize the params. This doesn't answer the question.Parallelepiped
T
3

arguments for

whenGET('/restpath/api/v1/')

and

expectGET('restpath/api/v1/books?limit=10&start=1')

are different. They should be same.

Touch answered 14/8, 2015 at 7:10 Comment(5)
updated the expectGet , wrote it wrong. It still does not workMisgive
i don't see it. your expectGET still has this extra ?limit=10&start=1 partTouch
Well the extra part is the dynamic query which needs to be mapped with the whenGet part of it. I have updated the questionMisgive
you need to use regex, refer #21169576Touch
Addition to @Touch answer , know I had the problem with $httpBackend.expectGET('/restpath/api/v1/books?limit=10&start=1'); , as my service was also running this request. When I commented I got the modified regex workingMisgive

© 2022 - 2024 — McMap. All rights reserved.