question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`allowUnmocked` with body matching fails to get the actual response

See original GitHub issue

What is the expected behavior?

When an interceptor does not match the body of the request, and allowUnmocked is true, the request should return the actual response.

What is the actual behavior?

The response object is somehow not getting the data from the request and just returns an undefined body.

Possible solution

I am a little bit stumped as to what is happening, but I did find that changing this line to add listeners on newReq that will propagate the event back to req will make the response return correctly. I have no idea why this works, and have been playing around with different possibilities, but none of them work except this one.

          // propagate(newReq, req);
          newReq.on('prefinish', function() {
            req.emit('prefinish');
          });
          newReq.on('socket', function(socket) {
            req.emit('socket', socket);
          });
          newReq.on('finish', function() {
            req.emit('finish');
          });
          newReq.on('response', function(incomingMessage) {
            req.emit('response', incomingMessage);
          });
          newReq.on('close', function() {
            req.emit('close');
          });

How to reproduce the issue

Runkit: Example link

Ran in Runkit.

const http = require('http')
const nock = require('nock@10.0.6')

const data = {bar: 'baz'}

const request1 = http.request({
  hostname: 'cat-fact.herokuapp.com',
  path: '/facts/random',
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': JSON.stringify(data).length
  }
})

request1.on('response', response => {
  response.on('data', data => console.log('real response:' + data.toString('utf8')));
});
request1.write(JSON.stringify(data))
request1.end()

// now we mock
nock('http://cat-fact.herokuapp.com')
  .get("/facts/random", { bar: 'baz' }, { allowUnmocked: true })
  .reply(200, { data: true })
  .persist();

const request2 = http.request({
  hostname: 'cat-fact.herokuapp.com',
  path: '/facts/random',
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': JSON.stringify(data).length
  }
})

request2.on('response', response => {
  response.on('data', data => console.log('mocked response (matched body): ' + data.toString('utf8')));
});
request2.write(JSON.stringify(data))
request2.end()

data.bar = 'biz';

const request3 = http.request({
  hostname: 'cat-fact.herokuapp.com',
  path: '/facts/random',
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': JSON.stringify(data).length
  }
})

request3.on('response', response => {
  response.on('data', () => console.log('This will not be logged'));
  response.on('end', () => console.log('Empty response (when the mock exists but the body did not match)'));
});
request3.write(JSON.stringify(data))
request3.end()

Does the bug have a test case?

Not that I can find.

Versions

Software Version(s)
Nock 10.0.6 & 11.0.0-beta.6
Node v9.11.2 & v10

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
mastermattcommented, May 29, 2019

This is fixed with propagate 2.0.1, correct?

1reaction
Americascommented, Apr 8, 2019

Context:

propagate replaces the emit method with its own method that is not returning whether the event is handled or not. As we can see in the docs, emit Returns true if the event had listeners, false otherwise.

This causes node’s http class to discard the response, since it thinks that there are no listeners for the response event. Node is checking the response of calling req.emit('response', res);, which with the propagate’s emit method, is always undefined.

Read more comments on GitHub >

github_iconTop Results From Across the Web

allowUnmocked causes no requests to match when query is ...
Yes, when we have allowUnmocked:true , request is mocked when it exactly ... { console.log('response: ' + body); } else { console.log(error ?...
Read more >
node.js - Nock: No match for request - Stack Overflow
Just add flag in scope { allowUnmocked: true } ... that would be executed by Node in order to avoid the 'Nock: No...
Read more >
nock - npm
Return true if it should be considered a match: ... In Nock 10 and earlier, the error was sent in the response body,...
Read more >
filteringRequestBody JavaScript and Node.js code examples
test('get a new auth token if not present in request headers', ... test('reject if auth request fails (non JSON error response)', () =>...
Read more >
nock - npm.io
Common issues. "No match for response" when using got with error responses. Got automatically retries failed requests twice. That means if you have...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found