18

I need to mock client side HTTP requests. I'm using isomorphic-fetch in the client side and I'm using mocha and nock for testing and mocking. All my client requests are based on relative path. Due to this I'm unable to provide host name for the nock. Is there a work around.

Client side:

fetch('/foo') //hostname: http://localhost:8080
.then(res => res.json())
.then(data => console.log(data))
.catch(e => console.log(e))

Test suite

nock('/')
.get('/foo')
.reply(200, {data: "hello"})

This is failing as I'm not giving the proper hostname for the nock. Am I doing something wrong?

Pranesh Ravi
  • 15,581
  • 6
  • 40
  • 61

5 Answers5

6

For anyone interested: In my react/webpack project I solved this by prepending the fetch url with 'http://localhost' when NODE_ENV is set to 'test'.

example:

const testing = process.env.NODE_ENV === 'test';
const apiUrl = `${testing ? 'http://localhost' : ''}/api`;

function getStuffFromApi() {
  return fetch(apiUrl, ...)
}

This way, in my test I can always use nock like so:

nock('http://localhost')
  .get('/api')
  .reply(200, {data: 'hello'})

NOTE: When running my tests, NODE_ENV gets set to 'test'

0xRm
  • 1,164
  • 7
  • 11
2

Found a workaround for this. Have a _ajax-setup.js in your test folder

import $ from 'jquery'

$(document).ajaxSend((event, jqxhr, settings) => {
  settings.url = 'http://0.0.0.0' + settings.url;
})

The thing to note is that this file has to run First and Only Once. Having it as a file runs only once and _ before it makes it alphabetically first.

Later you can test your code with

nock('http://0.0.0.0')
.get('/foo')
.reply(200, {data: "hello"})
bigOmega
  • 341
  • 2
  • 13
2

For axios I added following to my test file. This helped overcome this limitation.

    axios.defaults.baseURL='http://localhost:4000/';

Please note that this is a global variable. With this the actual code can live with relative URL and there is no need to check testing flag in it.

Amit Teli
  • 737
  • 8
  • 21
1

I just asked a similar question on Nock's repository. Apparently this is not supported: https://github.com/pgte/nock/issues/431

lior
  • 447
  • 3
  • 12
1

kudresov's reply to liorbauer's issue describes a Jest-specific workaround.

Put this into __mocks__/isomorphic-fetch.js:

const fetch = require.requireActual('isomorphic-fetch');

module.exports = (url, config) => {
  return fetch('https://localhost' + url, config);
};

Jest then automatically replaces all requires (or imports) for this node module.

In other test frameworks you could use something like rewire

Aaron
  • 1,733
  • 4
  • 25
  • 31