5

I'm writing code interacting with PayPal classic API. The first part of this interaction is to send request to PayPal and get a token from them. For that I use simple https request:

function makePayPalRequestForToken(options, callback) {

var requestOptions = {
    host: config.paypal.endpoint,
    path: '/nvp?' + qs.stringify(options),
    method: 'GET'
};
var req = https.get(requestOptions, function(res) {
    var data = '';

    res.on('data', function(chunk) {
      data = data + chunk;
    });

    res.on('end', function() {
      callback(null, data);
    });
});

req.on('error', function(e) {
    callback(e);
});

}

It works perfectly ok with PayPal sandbox, however, now I want to unit test my code and I don't know how to mock the response I get from PayPal.

I checked that the row response from PayPal is following:

<Buffer 54 4f 4b 45 4e 3d 45 43 25 32 64 35 44 53 33 38 35 31 37 4e 4e 36 36 37 34 37 33 4e 26 54 49 4d 45 53 54 41 4d 50 3d 32 30 31 35 25 32 64 30 35 25 32 64 ...>

So it looks like binary data. I wanted to use nock to mock the response, but I wonder how I could do this? How to make nock to response with the binary version of my response?

I tried something like this:

nock('https://' + config.paypal.endpoint)
                    .filteringPath(function() {
                       return '/';
                     })
                    .get('/')
                    .reply(200, 'myresponse', {'content-type': 'binary'});

But then I'm getting:

Uncaught Error: stream.push() after EOF

and it looks like no data is send in the mocked response.

Jakub
  • 3,129
  • 8
  • 44
  • 63

1 Answers1

6

If you are at a loss as to how to capture the response you are getting from the actual server and replicate it in nock, then read up on nock's awesome recording capability.

Use nock.recorder.rec() to record the actual response from the server. Use nock.recorder.play() to get the results. It should be an object which you can stringify to JSON. Put the JSON in a file and you can use nock.load() to use in your unit tests.

UPDATE: After some back and forth in the comments, it came to light that the specific issue OP is facing may be fixed by updating Node to v0.12.4 or later. This commit in particular looks like it might be relevant.

Trott
  • 66,479
  • 23
  • 173
  • 212
  • Thanks for pointing me to the recording feature. Unfortunately, even if I use the recorded response I still get "Uncaught Error: stream.push() after EOF" error when running my test. – Jakub May 25 '15 at 10:07
  • What line throws the error? Is it in your callback? – Trott May 25 '15 at 14:37
  • No, it looks that the error comes from nock: Uncaught Error: stream.push() after EOF at readableAddChunk (_stream_readable.js:146:15) at Readable.push (_stream_readable.js:127:10) at emitChunk (/Users/.../node_modules/nock/lib/request_overrider.js:441:26) at processImmediate (timers.js:330:15) – Jakub May 26 '15 at 06:10
  • What version of Node are you using? – Trott May 26 '15 at 14:44
  • Can you update to v0.12.4 and see if you still experience the problem? 0.12.4 landed the patch at https://github.com/joyent/node/commit/f2b297cc7ca1a7a4f4abd356bd1ad0af09e1b26b and it seems to address a problem that looks an awful lot like the one you are describing. – Trott May 27 '15 at 02:36
  • Yep, updating node was the first thing I did when I came home after reading your question about node version :) It helped! :) Thanks! – Jakub May 27 '15 at 09:19