I have a module that's supposed to call a local fetch wrapper. To check whether the get module calls the fetch wrapper correctly I'm mocking it and returning a spy like so:
// get.js
import fetch from '../fetch'
const get = (endpoint, token) => {
const headers = new Headers()
if (token) {
headers.append('Authorization', `Bearer ${token}`)
}
const init = {
headers,
method: 'GET'
}
return fetch(new Request(endpoint, init))
}
export default get
// get.test.js
import 'isomorphic-fetch'
import get from './get'
describe('get', () => {
it('calls fetch with a request', () => {
// I'm expecting this spy to be called by get
const mockFetch = jest.fn()
jest.mock('../fetch', () => jest.fn(mockFetch))
get('endpoint', 'token')
expect(mockFetch).toHaveBeenCalled()
})
})
But when I run it jest fails with:
expect(jest.fn()).toHaveBeenCalled()
Expected mock function to have been called.
So why isn't it calling the mock?
I have a module that's supposed to call a local fetch wrapper. To check whether the get module calls the fetch wrapper correctly I'm mocking it and returning a spy like so:
// get.js
import fetch from '../fetch'
const get = (endpoint, token) => {
const headers = new Headers()
if (token) {
headers.append('Authorization', `Bearer ${token}`)
}
const init = {
headers,
method: 'GET'
}
return fetch(new Request(endpoint, init))
}
export default get
// get.test.js
import 'isomorphic-fetch'
import get from './get'
describe('get', () => {
it('calls fetch with a request', () => {
// I'm expecting this spy to be called by get
const mockFetch = jest.fn()
jest.mock('../fetch', () => jest.fn(mockFetch))
get('endpoint', 'token')
expect(mockFetch).toHaveBeenCalled()
})
})
But when I run it jest fails with:
expect(jest.fn()).toHaveBeenCalled()
Expected mock function to have been called.
So why isn't it calling the mock?
Share Improve this question asked Jan 20, 2017 at 11:34 user5918874user59188741 Answer
Reset to default 7The problem is that all jest.mock
statements are hoisted to the top of code block. So even if you write it into the middle of your test it will be run as the first statement of your test and there is no way to have a specific return value. So how to fix this? First put the mock statement after your import statements to make clear that the mocking not happening in the test. Then import the module in your test. So this will be the result of the jest.fn()
in your mock statement. As fetch
is a spy now you can test on this that fetch
was called.
import 'isomorphic-fetch'
import get from './get'
import fetch from '../fetch'
jest.mock('../fetch', () => jest.fn())
describe('get', () => {
it('calls fetch with a request', () => {
get('endpoint', 'token')
expect(fetch).toHaveBeenCalled()
})
})