Comment mettre à L'Essai 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 action et réduire le code javascript, mais quand il s'agit de tester mes composants il lance toujours certains erreur.

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(<PhoneVerification {...fakeStore}/>);
    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 string (for built-in components) or a class/function (for composite components) but got: undefined.
<!-On a essayé de passer des espions aux sinons aux chai-spies.

Comment tester mon Unité de composants connectés React-Redux (composants intelligents)?

40
demandé sur Ayushya 2016-02-01 16:05:16

4 réponses

Une jolie manière de faire ceci est de l'exporter votre plaine composant et le composant enveloppé dans connect. La nommée à l'exportation serait le composant, la valeur par défaut est le enveloppés composant:

export class Sample extends Component {

    render() {
        let { verification } = this.props;
        return (
            <h3>This is my awesome component.</h3>
        );
    }

}

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'.

38
répondu Ashwin van Dijk 2016-02-23 13:34:42

Vous pouvez tester votre composant connecté et je pense que vous devriez le faire. Vous pouvez vouloir tester le composant non connecté d'abord, mais je suggère que vous n'aurez pas la couverture de test complète sans également tester le composant connecté.

ci-dessous est 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
        <Provider store={store}>
          <SongForm
            screen="add"
            disabled={false}
            handleFormSubmit={nullFcn1}
            handleModifySong={nullFcn2}
            handleDeleteSong={nullFcn3}
          />
        </Provider>
      );

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 (
        <form onSubmit={handleSubmit(handleFormSubmit)}>
            ....
        </form>

};

const mapStateToProps = (/* object */ state) /* object */ => ({
    songTags: state.songs.songTags
});
const mapDispatchToProps = () /* object..function */ => ({ /* ... */ });

export default connect(mapStateToProps, mapDispatchToProps)(SongForm)

Vous pouvez vouloir créer un magasin avec pure Redux. redux-mock-store est juste une version légère de celui-ci destiné à l'essai.

Vous pouvez utiliser react-addons-test-utils au lieu de l'Enzyme d'airbnb.

j'utilise le chai-enzyme d'airbnb pour avoir des options D'attente réactives. Il n'était pas nécessaire dans cet exemple.

10
répondu JohnSz 2016-07-28 00:53:43

le problème avec la réponse acceptée est que nous exportons quelque chose inutilement juste pour pouvoir le tester. Et exporter une classe juste pour la tester n'est pas une bonne idée à mon avis.

Voici une solution plus nette sans devoir exporter autre chose que le composant connecté:

si vous utilisez jest, vous pouvez vous moquer connect méthode de retour trois choses:

  1. mapStateToProps
  2. mapDispatchToProps
  3. ReactComponent

le Faire est assez simple. Il y a 2 façons: les moqueries en ligne ou les moqueries globales.

1. En ligne fantaisie

ajouter l'extrait suivant avant la fonction describe du test.

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

2. En utilisant le fichier maquette

  1. Créer un fichier __mocks__/react-redux.js à la racine (où l'emballage.json est situé)
  2. ajouter l'extrait suivant dans le fichier.

module.exports = {
  connect: (mapStateToProps, mapDispatchToProps) => (ReactComponent) => ({
    mapStateToProps,
    mapDispatchToProps,
    ReactComponent,
  }),
  Provider: ({children}) => children
};

après vous être moqué, vous pourrez accéder à tous les trois ci-dessus en utilisant Container.mapStateToProps,Container.mapDispatchToProps et Container.ReactComponent.

le conteneur peut être importé en faisant simplement

import Container from '<path>/<fileName>.container.js'

j'Espère que ça aide.

notez que si vous utilisez file mock. Le fichier moqué sera utilisé globalement pour tous les cas de test(sauf si vous faites jest.unmock('react-redux')) avant l'essai.

3
répondu Rahul Gaba 2018-03-23 15:10:46

essayez de créer 2 fichiers, un avec le composant lui-même, n'étant pas au courant d'aucun magasin ou quoi que ce soit (Phonevérification-component.js). Puis le deuxième (Phonevérification.js), que vous utiliserez dans votre application et qui ne renvoie que le premier composant souscrit à stocker via connect fonction, quelque chose comme

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

alors vous pouvez tester votre composant "muet" en demandant PhoneVerification-component.js dans votre test et de lui fournir les accessoires nécessaires moqués. Il ne sert à rien de tester déjà testé (connect decorator, mapStateToProps, mapDispatchToProps etc...)

1
répondu george.cz 2016-02-17 15:16:14