fetch-mock
fetch-mock copied to clipboard
regexp matchers cannot always be overwritten
Version: latest
Description: when you enable overwriteRoutes, and mock a route twice with a RegExp, it will not mock with the response of the second mock unless you share the same RegExp instance.
Reproduction:
import fetchMock from 'fetch-mock'
fetchMock.config.overwriteRoutes = true
it('foo', () => {
fetchMock.mock(/example\.com/, 200)
const successResponse = await fetch('example.com')
expect(successResponse.status).toBe(200)
fetchMock.mock(/example\.com/, 404)
const failureResponse = await fetch('example.com')
expect(failureResponse.status).toBe(404) // nope, its 200
})
If, however you amend the above to
import fetchMock from 'fetch-mock'
fetchMock.config.overwriteRoutes = true
const exampleMatcher = /example\.com/
it('foo', () => {
fetchMock.mock(exampleMatcher, 200)
const successResponse = await fetch('example.com')
expect(successResponse.status).toBe(200)
fetchMock.mock(exampleMatcher, 404)
const failureResponse = await fetch('example.com')
expect(failureResponse.status).toBe(404) // yep works!
})
it works as expected.
I narrowed this problem down to some code that did a triple equality check but I don't remember where I saw it. That would explain though why a shared reference works, but the earlier one doesn't.
I think this is expected behaviour, though I agree it's not obvious and not documented very well.
To get more transparent behaviour it's best to name your routes
it('foo', () => {
fetchMock.mock(/example\.com/, 200, {name: 'myroute'})
const successResponse = await fetch('example.com')
expect(successResponse.status).toBe(200)
fetchMock.mock(/example\.com/, 404, , {name: 'myroute'})
const failureResponse = await fetch('example.com')
expect(failureResponse.status).toBe(404) // should be 404
})
Thank you, naming mocked routes was exactly what we needed to do!