fetch-mock: Cannot mock relative URLs in v3.0.4

As of v3.0.4, mocking a relative URL results in an Error being thrown from the dependency module node-fetch:

Error: only absolute urls are supported
    at new Request (node_modules/fetch-mock/node_modules/node-fetch/lib/request.js:34:9)
    at toRequest (node_modules/fetch-mock/src/fetch-mock.js:65:13)
    at Object.route.matcher (node_modules/fetch-mock/src/fetch-mock.js:111:15)
    at node_modules/fetch-mock/src/fetch-mock.js:233:15
    at Array.some (native)
    at routes.forEach.routes.forEach.routes.some (node_modules/fetch-mock/src/fetch-mock.js:231:11)
    at mock (node_modules/fetch-mock/src/fetch-mock.js:329:21)
    ....

In my use case, I am writing tests for a Redux application which uses fetch to grab some i18n data defined in a JSON file. The code I am testing looks like this:

fetch(`public/i18n/${locale}.json`)
  .then(/* ...snip... */)

The tests are written in mocha and are executed through Node.js, so I use isomorphic-fetch assigned to the global object inside the test, to fill in for the browser’s fetch function, and use fetch-mock to mock the response:

import fetchMock from 'fetch-mock'
import fetch from 'isomorphic-fetch'

global.fetch = fetch
/* ...snip... */
fetchMock.mock(`public/i18n/${locale}.json`, { /* fixture i18n data */ })

This code worked fine in v3.0.3 as fetch-mock wasn’t using Request from node-fetch, which sets the absolute URL limitation (LIMITS.md in node-fetch repository).

Related issue in node-fetch: https://github.com/bitinn/node-fetch/issues/43

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 2
  • Comments: 28 (8 by maintainers)

Most upvoted comments

Getting TypeError: this.realFetch is not a function as well whenever I try to make a POST request in non-testing code

fetch(myApiRoute, {method: 'POST'})

Edit: Just realized this will work, it needs to have a fetch passed into its context, not the global context.

fetchMock.useNonGlobalFetch(fetch)
fetchMock.mock(myApiRoute, 'POST', payload)

@wheresrhys it seems like some people have resolved this issue but I’m doing everything the same and still getting the error from node-fetch:

Error: only absolute urls are supported

The only thing I’ve noticed about the example from @dr-nick that’s different than mine (and I understand it is just a snippet and not full working code) is that it’s not testing the response from the async action (using a then statement). Once I try to return the response from the async request, I still get the error, and I don’t see a way that error wouldn’t be thrown judging by the stack trace and the construct of the Request object.

Sorry to reopen this but I just wanted to know if this was considered resolved or if there was still being more done to solve it.

Here’s a snippet of my test that’s failing:

describe("async", function() {
    beforeEach(function() {
        fetchMock.useNonGlobalFetch(fetch);
        fetchMock.mock(API_URL, { body: { response: ['value'] }});
    })

    afterEach(function() {
        fetchMock.restore();
    })

    it("runs fetch and collects response", function() {
        const store = mockStore({entities: {}});
        return store.dispatch(actions.action())
            .then(() => {
                expect(true).to.equal(true);
            })
    })
})

I had exactly this problem, using fetch-mock 4.1.1 and isomorphic-fetch 2.2.1. To resolve it I had to do all of the following:

  • don’t import isomorphic-fetch in the action code (under test). If I did, I always got the only absolute urls error.
  • to polyfill for older browsers, import whatwg-fetch; in the action instead.
  • in the test class, import isomorphic-fetch; alongside import fetch-mock;

(edited following further simplification)

Hope this helps.