Component.js
import React from 'react'
import request from 'superagent'
export default React.createClass({
getInitialState() {
return {cats: []}
},
componentDidMount() {
request('/api', (err, res) => {
if (err) return;
this.setState({
cats: res.body.results
})
})
},
render() {
let cats = this.state.cats
let catsList = (
<ul>
{cats.map((c) => <li key={c.id}>cat</li>)}
</ul>
)
return (
<div>
{cats.length ? catsList : null}
</div>
)
}
})
Component.test.js
jest.unmock('../app.js')
jest.unmock('superagent')
import React from 'react'
import {mount} from 'enzyme'
import nock from 'nock'
import App from '../app.js'
describe('App', () => {
let ajaxFn
beforeEach(() => {
ajaxFn = nock('http://localhost')
.get('/api')
.reply(200, {
results: [{id: 1}, {id: 2}, {id: 3}]
})
})
it('renders correct number of cats', () => {
let wrapper = mount(<App />)
expect(wrapper.state('cats').length).toBe(3)
})
})
The test does not pass. wrapper.state('cats').length
is always 0
.
I understand that setState
doesn't guarantee to update state immediately,
however if I log 'cats' in the component, I can see it updating.
You may call setState() immediately in componentDidMount() . It will trigger an extra rendering, but it will happen before the browser updates the screen.
setState(state) => Self. A method to invoke setState() on the root component instance similar to how you might in the definition of the component, and re-renders. This method is useful for testing your component in hard to achieve states, however should be used sparingly.
What to do when you want to test that a function is been called, on componentDidMount() React lifecycle Method. Basically the component code looks like this: state = { randomStateToPopulate: [] }; // Test componentDidMount componentDidMount() { this. randomFunction(); } randomFunction= () => { listRandomData().
If you end up setting state in your component in some context that enzyme doesn't know about, you will have to manually call .update()
on the wrapper in order for it to get the updated version of the render tree.
it('renders correct number of cats', () => {
let wrapper = mount(<App />)
expect(wrapper.update().state('cats').length).toBe(3)
})
I had a similar problem and it was necessary to return a promise from the it
callback and check the expectation in the then
method of the promise.
In your case (assuming ajaxFn was a promise, or you could turn it into one) I think this would be approximately:
it('renders correct number of cats', () => {
let wrapper = mount(<App />)
return ajaxFn.then(() => {
expect(wrapper.state('cats').length).toBe(3);
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With