J'utilise Enzyme , et nous pouvons réellement utiliser le composant exemple donné dans les documents comme fondement de ma question.
Supposons que ce <Foo />
le composant utilise un <Link>
composant de ReactRouter et nous devons donc l'envelopper dans un <MemoryRouter>
pour tester.
C'est ici que se trouve le problème.
it('puts the lotion in the basket', () => {
const wrapper = mount(
<MemoryRouter>
<Foo />
</MemoryRouter>
)
wrapper.state('name') // this returns null! We are accessing the MemoryRouter's state, which isn't what we want!
wrapper.find(Foo).state('name') // this breaks! state() can only be called on the root!
})
Donc, vous ne savez pas exactement comment accéder à l'état du composant local lorsque vous utilisez <MemoryRouter>
.
Peut-être que je fais un test ignorant? Essayer d'obtenir/définir l'état du composant est-il une mauvaise pratique dans les tests? Je ne peux pas imaginer que ce soit le cas, car Enzyme a des méthodes pour obtenir/définir l'état des composants.
Je ne sais pas comment on est censé accéder aux composants internes d'un composant enveloppé dans <MemoryRouter>
.
Toute aide serait grandement appréciée!
Il semble donc qu'avec la dernière version d'Enzyme, il existe un correctif potentiel pour ce problème d'accès à l'état sur un composant enfant.
Disons que nous avons <Foo>
(Notez l'utilisation de React Router's <Link>
)
class Foo extends Component {
state = {
bar: 'here is the state!'
}
render () {
return (
<Link to='/'>Here is a link</Link>
)
}
}
Remarque: Le code suivant est uniquement disponible dans Enzyme v3.
Revisitant le code de test, nous pouvons maintenant écrire ce qui suit
it('puts the lotion in the basket', () => {
const wrapper = mount(
<MemoryRouter>
<Foo />
</MemoryRouter>
)
expect(wrapper.find(Foo).instance().state).toEqual({
bar: 'here is the state!'
})
})
En utilisant wrapper.find(Child).instance()
, nous pouvons accéder à l'état de Child
même s'il s'agit d'un composant imbriqué. Dans les versions précédentes d'Enzyme, nous ne pouvions accéder qu'à instance
à la racine. Vous pouvez également appeler la fonction setState
sur le wrapper Child
!
Nous pouvons utiliser un modèle similaire avec nos tests rendus superficiellement
it('puts the lotion in the basket shallowly', () => {
const wrapper = shallow(
<MemoryRouter>
<Foo />
</MemoryRouter>
)
expect(wrapper.find(Foo).dive().instance().state).toEqual({
bar: 'here is the state!'
})
})
Notez l'utilisation de dive
dans le test superficiel, qui peut être exécuté sur un seul nœud non DOM, et renverra le nœud, rendu superficiel.
Réfs:
J'ai pensé que cela pourrait être utile pour vous, alors que je suis tombé dessus et que j'ai une solution.
Dans mon cas, j'ai un composant qui est connecté à redux.
class ComponentName extends Component {
...
}
export default connect(
mapStateToProps,
{
...
}
)(ComponentName );
connect () est évidemment un composant HOC. Alors, comment pouvons-nous accéder au "ComponentName" ici?
Très simple:
component
.find(ComponentName)
.children()
.first()
.props() // returns ComponentName's props