Skip to content

Instantly share code, notes, and snippets.

@indiesquidge

indiesquidge/App.js

Created Oct 6, 2017
Embed
What would you like to do?
Mocking globals in Jest
import React, { Component } from 'react';
class App extends Component {
constructor () {
super()
this.state = {
name: null,
imgUrl: null
}
}
async componentDidMount () {
// notice that we have are using `fetch` as a global here,
// which means we will need to mock the global in our tests
const response = await fetch(`https://api.github.com/users/gaearon`)
const userJSON = await response.json()
this.setState({
name: userJSON.name,
imgUrl: userJSON.avatar_url
})
}
render() {
return this.state.name ? (
<div>
<img src={this.state.imgUrl} alt="github avatar" height="100px" />
<h1>{this.state.name}</h1>
</div>
) : (
<div>Loading…</div>
)
}
}
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { configure, mount } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
// http://airbnb.io/enzyme/docs/installation/index.html
configure({ adapter: new Adapter() })
it('displays the GitHub username and avatar image', async () => {
const wrapper = mount(<App />)
expect(wrapper.state()).toEqual({
name: null,
imgUrl: null
})
// since we are calling `fetch` directly in `componentDidMount`, we need to
// await for that lifecycle to finish before we can assert against the wrapper.
// Also notice that the `fetch` global is nowhere to be found in this file; it
// is defined in `src/setupTests.js`.
await wrapper.instance().componentDidMount()
expect(wrapper.state()).toEqual({
name: 'GitHub name',
imgUrl: 'GitHub avatar_url'
})
})
// If you are using Create React App and you'd like `fetch` to be mocked out
// for all tests across the app, you can include the global in `src/setupTests.js`.
// CRA uses the Jest config option `setupTestFrameworkScriptFile`, so if you are
// not using CRA you can still create a file to mock out your globals.
//
// Notice that this exposes the pitfalls of using fetch as a global in our
// `<App>` component. Looking at our test file, it is not clear how the `fetch`
// global is even working in our test without a knowledge that this `setupTests`
// file exists.
//
// On top of this, if we had multiple components making fetch requests, we would
// have to keep adding properties to our returned object here, even though only
// some of them would be used for each test.
//
// refs:
// - http://ow.ly/MfJ030fHhTL (Create React App: Initializing Test Environment)
// - http://ow.ly/Xih030fHi06 (Jest setupTestFrameworkScriptFile config option)
const fetch = async () => ({
json: async () => ({
name: 'GitHub name',
avatar_url: 'GitHub avatar_url'
})
})
global.fetch = fetch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.