Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return object instead of string for response with nock?

When I stub request with nock it returns String result instead of Object even with 'Content-Type': 'application/json':

var response = {
  success: true,
  statusCode: 200,
  body: {
    "status": "OK",
    "id": "05056b27b82",
  }
};

Test.BuildRequest();
Test.SendRequest(done);

nock('https://someapi.com')
  // also tried
  // .defaultReplyHeaders({
  //   'Content-Type': 'application/json',
  //   'Accept': 'application/json'
  // })

  .post('/order')
  .reply(200, response.body, 
    'Content-Type': 'application/json',
    'Accept': 'application/json');

checking:

console.log(put.response.body);
console.log(put.response.body.id);

output:

{"status":"OK","id":"05056b27b82"}
undefined

In code I use request module that returns Object with the same data. I tried also sinon (doesn't work for me) and fakeweb but got the same issue.

My code, which i'm trying to test:

var request = require('request');
// ...

request(section.request, function (err, response, body) {
  if (err || _.isEmpty(response))
    return result(err, curSyndication);

  //if (_.isString(body))
  //    body = JSON.parse(body);

  section.response.body = body;
  console.log(body.id); // => undefined (if uncomment previous code - 05056b27b82)

  _this.handleResponse(section, response, body, result);
});

And it returns an object in real requests.

PS. I could add next code in my response handler:

if (_.isString(body))
  body = JSON.parse(body);

But some of queries returns xml string, and i'm not responsible for such changes.

Fakeweb:

fakeweb.registerUri({
  uri: 'https://someapi.com/order',
  body: JSON.stringify({
    status: "OK",
    id: "05056b27b82",
  }),
  statusCode: 200,
  headers: {
    'User-Agent': 'My requestor',
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  }
});
Test.SendRequest(done);

Same results.

Updated:

I read a couple of articles, that uses JSON Object, without parsing it (with nock), so it should returns JSON object, same way how request library do that.

like image 776
zishe Avatar asked Dec 31 '14 05:12

zishe


People also ask

How do you pass a header on a nock?

Specifying Request HeadersThe function will be passed the header value. If reqheaders is not specified or if host is not part of it, Nock will automatically add host value to request header. If no request headers are specified for mocking then Nock will automatically skip matching of request headers.

What is object object in node?

[object Object] occurs in the log when there is an object with keys and values. You can access properties in an object wth dot notation (.) e.g objectName. propertyName.

What is a characteristic of the Nock library?

Nock is an HTTP server mocking and expectations library for Node. js. Nock works by overriding the http. request and http. ClientRequest functions, intercepting all requests made to a specified URL and returning specified responses that mimic the data that the real URL would return.


1 Answers

There is nothing wrong with your nock configuration however you haven't told request to parse the response as JSON.

From the request method documentation (emphasis on me):

json - sets body but to JSON representation of value and adds Content-type: application/json header. Additionally, parses the response body as JSON.

The callback argument gets 3 arguments:

  • An error when applicable (usually from http.ClientRequest object)
  • An http.IncomingMessage object
  • The third is the response body (String or Buffer, or JSON object if the json option is supplied)

So you need to set the json property to true on your section.request object:

var request = require('request');
// ...

section.request.json = true;
request(section.request, function (err, response, body) {
  //..
});
like image 122
nemesv Avatar answered Oct 06 '22 07:10

nemesv