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)
})
})
Le test ne passe pas. wrapper.state('cats').length
est toujours 0
.
Je comprends que setState
ne garantit pas la mise à jour immédiate de l’état, Toutefois, si je consigne les "chats" dans le composant, je peux le voir se mettre à jour.
Si vous définissez l'état de votre composant dans un contexte inconnu de l'enzyme, vous devrez appeler manuellement .update()
sur le wrapper pour qu'il obtienne la version mise à jour de l'arborescence de rendu.
it('renders correct number of cats', () => {
let wrapper = mount(<App />)
expect(wrapper.update().state('cats').length).toBe(3)
})
J'ai eu un problème similaire et il était nécessaire de renvoyer une promesse du rappel it
et de vérifier l'espérance dans la méthode then
de la promesse.
Dans votre cas (en supposant que ajaxFn était une promesse, ou vous pourriez en faire une), je pense que ce serait approximativement:
it('renders correct number of cats', () => {
let wrapper = mount(<App />)
return ajaxFn.then(() => {
expect(wrapper.state('cats').length).toBe(3);
}
})
Je ne connais pas toutes les bibliothèques que vous utilisez, mais comme votre code est exécuté de manière asynchrone, le test se termine avant que l'état ne puisse être mis à jour. J'ai pu résoudre ce problème en ajoutant async/wait au test:
it('renders correct number of cats', async () => {
let wrapper = await mount(<App />)
expect(wrapper.state('cats').length).toBe(3)
})