Comment tester les composants connectés React-Redux?

J’utilise Mocha, Chai, Karma, Sinon, Webpack pour les tests unitaires.

J’ai suivi ce lien pour configurer mon environnement de test pour le code React-Redux.

https://medium.com/@scbarrus/how-to-get-test-coverage-on-react-with-karma-babel-and-webpack-c9273d805063#.7kcckz73r

Je peux tester avec succès mon code javascript d’action et de réducteur, mais quand il s’agit de tester mes composants, il génère toujours des erreurs.

import React from 'react'; import TestUtils from 'react/lib/ReactTestUtils'; //I like using the Test Utils, but you can just use the DOM API instead. import chai from 'chai'; // import sinon from 'sinon'; import spies from 'chai-spies'; chai.use(spies); let should = chai.should() , expect = chai.expect; import { PhoneVerification } from '../PhoneVerification'; let fakeStore = { 'isFetching': false, 'usernameSettings': { 'errors': {}, 'username': 'sahil', 'isEditable': false }, 'emailSettings': { 'email': 'test@test.com', 'isEmailVerified': false, 'isEditable': false }, 'passwordSettings': { 'errors': {}, 'password': 'showsomestarz', 'isEditable': false }, 'phoneSettings': { 'isEditable': false, 'errors': {}, 'otp': null, 'isOTPSent': false, 'isOTPReSent': false, 'isShowMissedCallNumber': false, 'isShowMissedCallVerificationLink': false, 'missedCallNumber': null, 'timeLeftToVerify': null, '_verifiedNumber': null, 'timers': [], 'phone': '', 'isPhoneVerified': false } } function setup () { console.log(PhoneVerification); // PhoneVerification.componentDidMount = chai.spy(); let output = TestUtils.renderIntoDocument(); return { output } } describe('PhoneVerificationComponent', () => { it('should render properly', (done) => { const { output } = setup(); expect(PhoneVerification.prototype.componentDidMount).to.have.been.called; done(); }) }); 

Cette erreur suivante apparaît avec le code ci-dessus.

 FAILED TESTS: PhoneVerificationComponent ✖ should render properly Chrome 48.0.2564 (Mac OS X 10.11.3) Error: Invariant Violation: Element type is invalid: expected a ssortingng (for built-in components) or a class/function (for composite components) but got: undefined. 

Essayé de passer de sinon espions aux chai-espions.

Comment dois-je tester mes composants connectés React-Redux (Smart Components)?

Une manière plus simple de procéder consiste à exporter à la fois votre composant ordinaire et le composant enveloppé dans connect. L’exportation nommée serait le composant, la valeur par défaut est le composant encapsulé:

 export class Sample extends Component { render() { let { verification } = this.props; return ( 

This is my awesome component.

); } } const select = (state) => { return { verification: state.verification } } export default connect(select)(Sample);

De cette façon, vous pouvez importer normalement dans votre application, mais quand il s’agit de tester, vous pouvez importer votre exportation nommée en utilisant import { Sample } from 'component' .

Vous pouvez tester votre composant connecté et je pense que vous devriez le faire. Vous voudrez peut-être tester d’abord le composant non connecté, mais je suggère que vous ne disposiez pas d’une couverture de test complète sans tester également le composant connecté.

Voici un extrait non testé de ce que je fais avec Redux et Enzyme. L’idée centrale est d’utiliser Provider pour connecter l’état en test au composant connecté en test.

 import { Provider } from 'react-redux'; import configureMockStore from 'redux-mock-store'; import SongForm from '../SongForm'; // import the CONNECTED component // Use the same middlewares you use with Redux's applyMiddleware const mockStore = configureMockStore([ /* middlewares */ ]); // Setup the entire state, not just the part Redux passes to the connected component. const mockStoreInitialized = mockStore({ songs: { songsList: { songs: { songTags: { /* ... */ } } } } }); const nullFcn1 = () => null; const nullFcn2 = () => null; const nullFcn3 = () => null; const wrapper = mount( // enzyme    ); const formPropsFromReduxForm = wrapper.find(SongForm).props(); // enzyme expect( formPropsFromReduxForm ).to.be.deep.equal({ screen: 'add', songTags: initialSongTags, disabled: false, handleFormSubmit: nullFcn1, handleModifySong: nullFcn2, handleDeleteSong: nullFcn3, }); ===== ../SongForm.js import React from 'react'; import { connect } from 'react-redux'; const SongForm = (/* object */ props) /* ReactNode */ => { /* ... */ return ( 
....
}; const mapStateToProps = (/* object */ state) /* object */ => ({ songTags: state.songs.songTags }); const mapDispatchToProps = () /* object..function */ => ({ /* ... */ }); export default connect(mapStateToProps, mapDispatchToProps)(SongForm)

Vous voudrez peut-être créer un magasin avec Redux pur. redux-mock-store est juste une version légère de ce produit destinée aux tests.

Vous pouvez utiliser react-addons-test-utils au lieu de l’enzyme airbnb.

J’utilise la chai-enzyme airbnb pour avoir des options attendues de React-aware. Cela n’était pas nécessaire dans cet exemple.

Le problème avec la réponse acceptée est que nous exportons inutilement des produits pour pouvoir les tester. Et exporter une classe juste pour la tester n’est pas une bonne idée à mon avis.

Voici une solution plus simple sans avoir besoin d’exporter autre chose que le composant connecté:

Si vous utilisez jest, vous pouvez simuler la méthode de connect pour renvoyer trois choses:

  1. mapStateToProps
  2. mapDispatchToProps
  3. ReactComponent

Cela est assez simple. Il existe deux façons: les simulations en ligne ou les simulacres globaux.

1. Utilisation de maquette en ligne

Ajoutez l’extrait suivant avant la fonction de description du test.

 jest.mock('react-redux', () => { return { connect: (mapStateToProps, mapDispatchToProps) => (ReactComponent) => ({ mapStateToProps, mapDispatchToProps, ReactComponent }), Provider: ({ children }) => children } }) 

Essayez de créer 2 fichiers, l’un avec le composant lui-même, ne connaissant aucun magasin ni aucun élément (PhoneVerification-component.js). Puis la deuxième (PhoneVerification.js), que vous utiliserez dans votre application et qui ne renvoie que le premier composant abonné à la banque via la fonction de connect , quelque chose comme:

 import PhoneVerificationComponent from './PhoneVerification-component.js' import {connect} from 'react-redux' ... export default connect(mapStateToProps, mapDispatchToProps)(PhoneVerificationComponent) 

Ensuite, vous pouvez tester votre composant “dumb” en demandant PhoneVerification-component.js dans votre test et en lui fournissant les accessoires nécessaires. Il n’y a pas de sharepoint test déjà testé (connect decorator, mapStateToProps, mapDispatchToProps etc …)