Reputation: 5051
I have a component that dispatches a fetch
request on mount, and displays the results.
I am trying to create a test snapshot of this component after the request is completed. I've been banging my head at this for quite some time now, here are the related question on SO that gave me no luck:
This is my fetch
mock:
// Mocking the global.fetch included in React Native
global.fetch = jest.fn()
// Helper to mock a success response (only once)
fetch.mockResponseSuccess = (body, status = 200) => {
fetch.mockImplementationOnce(() =>
Promise.resolve({
status,
json: () => Promise.resolve(JSON.parse(body))
})
)
}
// Helper to mock a failure response (only once)
fetch.mockResponseFailure = error => {
fetch.mockImplementationOnce(() => Promise.reject(error))
}
The component (simplified):
export class Posts extends Component {
constructor(props) {
super(props)
this.state = {
items: [],
loading: false
}
this._getItems()
}
async _getItems() {
const resp = await fetch(
"/user/recent_posts",
{
method: "GET"
}
)
this.setState({
items: resp.json["data"],
})
}
render() {
// renders this.state.items
}
This is the test:
test("view renders correctly", async done => {
fetch.mockResponseSuccess(
JSON.stringify({
data: [
{ caption: "test", likes: 100 },
{ caption: "test2", likes: 200 }
]
})
)
// also tried with setTimeout and setImidiate
const wrapper = await shallow(<Posts />) // also tried with react-test-renderer
await wrapper.update() // didn't work with or without
// await waitForState(wrapper, state => state.loading === false) --> didn't work
// process.nextTick(() => {.... --> didn't work
// jest.runTimersToTime(1) --> didn't work
expect(wrapper).toMatchSnapshot()
done()
})
The problem is that this.state.items
in the snapshot is always empty.
Upvotes: 0
Views: 374
Reputation: 5051
For future reference, here is what solved it for me:
test("view renders correctly", done => {
// mock response here...
const wrapper = shallow(<Posts />)
setImmediate(() => {
wrapper.update()
try {
expect(wrapper).toMatchSnapshot()
} catch (e) {
console.log(e)
}
done()
})
})
Upvotes: 1