My select component is like below
class Select extends React.component(){
render(){
return(
<select>
some options element return by ajax appended in here
</select>
)
}
}
How do check if select have some option in it after it has been updated by other ajax function
@craigcosmo how is it "updated"? In React, you'd generally have your ajax callback setState on the component, and then the render function would pivot based on this.state. If so, then you test it by using setState in enzyme, and making assertions on the wrapper.
Here is the code:
import axios from 'axios'
class Select extends React.component(){
constructor(){
super()
this.state.item=[]
}
componentWillMount(){
axios.get('http://domain.com/country_list')
.then(function (response) {
this.setState({item:response.data})
// reponse data ['america','singapore','vietnam']
})
}
render(){
return(
<select>
this.state.item.map((i) => {
<option value={i}>{i}</option>
})
</select>
)
}
}
Can you give me an example of the test code?
off the top of my head:
// do whatever you need to mock axios
const wrapper = shallow(<Select />); // componentWillMount will be called
// after axios has called the "then" callback:
wrapper.update();
// make your assertions
does that not work?
I'm afraid I'm gonna have to extend the question. How would you mock axios in this case? I updated the code above to be more specific. And it would be great If you can show a specific sample.
That's specific to axios. Perhaps sinon.stub(axios, 'get', () => Promise.resolve(fakeResponse))?
Since your component doesn't use any sort of dependency injection, if your test file can't access axios, you can use something like nock to fake the HTTP answer.
However, I would encourage you to split your component in two, one that simply takes care of this call, and then passes the corresponding data to its child, it will make it easier to test, and usually easier to reason about, see the smart/dumb component distinction.
This is what I get out so far:
import {expect} from 'chai'
import {shallow} from 'enzyme'
import sinon from 'sinon'
import Select from 'Select'
import axios from 'axios'
describe('select list', () => {
it('should have options', () => {
sinon.stub(axios, 'get', () => Promise.resolve(['de','am','hl']))
const wrapper = shallow(<Select />)
wrapper.update()
const actual = wrapper.find('option').length
expect(actual).to.not.equal(0)
})
})
Error: Attempted to wrap get which is already wrapped

@craigcosmo it's an async test. you need to either return a promise or have the mocha test take a done argument - and in this case, you need to wait until the axios-stubbed promise is done before calling update().
At this point this is not an enzyme issue, so I'm going to close it. Feel free to continue exploring how to use mocha here.
How would you actually do it?
const promise = Promise.resolve(['de','am','hl']);
sinon.stub(axios, 'get', () => promise);
const wrapper = shallow(<Select />);
return promise.then(() => {
wrapper.update();
// your assertions here
});
@craigcosmo Did you actually find a solution?
This is how the componentWillMount lifecycle method looks...
componentWillMount(){
axios.get('api/v1/getcall')
.then(function (response) {
this.setState({ item:response.data })
})
I am using axios-mock-adaptor to mock the axios calls, but ran into the same state as yours.
@parminder7 Ljharb's solution is the solution.
Most helpful comment