Code complet ici: https://gist.github.com/js08/0ec3d70dfda76d7e9fb4
Salut,
- J'ai une application où il montre différents modèles pour ordinateur de bureau et mobile en fonction de l'environnement de construction.
- Je parviens à le développer là où je dois masquer le menu de navigation de mon modèle mobile.
- en ce moment, je suis capable d'écrire un cas de test où il récupère toutes les valeurs via les proptypes et rend correctement
- mais je ne sais pas comment écrire les cas de test unitaires lorsque son mobile, il ne doit pas rendre le composant de navigation.
- J'ai essayé mais je suis confronté à une erreur ... pouvez-vous me dire comment y remédier.
- code de preuve ci-dessous.
Cas de test
import {expect} from 'chai';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import {SportsTopPortion} from '../../../src/components/sports-top-portion/sports-top-portion.jsx';
require('../../test-utils/dom');
describe('"sports-top-portion" Unit Tests', function() {
let shallowRenderer = TestUtils.createRenderer();
let sportsContentContainerLayout ='mobile';
let sportsContentContainerProfile = {'exists': 'hasSidebar'};
let sportsContentContainerAuthExchange = {hasValidAccessToken: true};
let sportsContentContainerHasValidAccessToken ='test';
it('should render correctly', () => {
shallowRenderer.render(<SportsTopPortion sportsWholeFramework={sportsContentContainerLayout} sportsPlayers={sportsContentContainerProfile} sportsAuthentication={sportsContentContainerAuthExchange} sportsUpperBar={{activeSportsLink:'test'}} />);
//shallowRenderer.render(<SportsTopPortion sportsWholeFramework={sportsContentContainerLayout} sportsPlayers={sportsContentContainerProfile} hasValidAccessToken={sportsContentContainerHasValidAccessToken} />);
let renderedElement = shallowRenderer.getRenderOutput();
console.log("renderedElement------->" + JSON.stringify(renderedElement));
expect(renderedElement).to.exist;
});
it('should not render sportsNavigationComponent when sports.build is mobile', () => {
let sportsNavigationComponent = TestUtils.renderIntoDocument(<SportsTopPortion sportsWholeFramework={sportsContentContainerLayout} sportsPlayers={sportsContentContainerProfile} sportsAuthentication={sportsContentContainerAuthExchange} sportsUpperBar={{activeSportsLink:'test'}} />);
console.log("sportsNavigationComponent------->" + JSON.stringify(sportsNavigationComponent));
//let footnoteContainer = TestUtils.findRenderedDOMComponentWithClass(sportsNavigationComponent, 'linkPack--standard');
//expect(footnoteContainer).to.exist;
});
});
Extrait de code où le cas de test doit être écrit
if (sports.build === 'mobile') {
sportsNavigationComponent = <div />;
sportsSideMEnu = <div />;
searchComponent = <div />;
sportsPlayersWidget = <div />;
}
Erreur
1) "sports-top-portion" Unit Tests should not render sportsNavigationComponent when sports.build is mobile:
Invariant Violation: Could not find "store" in either the context or props of "Connect(SportsDatabase)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(SportsDatabase)".
at Object.invariant [as default] (C:\sports-whole-page\node_modules\invariant\invariant.js:42:15)
at new Connect (C:\sports-whole-page\node_modules\react-redux\lib\components\createConnect.js:135:33)
at [object Object].ReactCompositeComponentMixin.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactCompositeComponent.js:148:18)
at [object Object].wrapper [as mountComponent] (C:\sports-whole-page\node_modules\react\lib\ReactPerf.js:66:21)
at Object.ReactReconciler.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactReconciler.js:37:35)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (C:\sports-whole-page\node_modules\react\lib\ReactMultiChild.js:241:44)
at ReactDOMComponent.Mixin._createContentMarkup (C:\sports-whole-page\node_modules\react\lib\ReactDOMComponent.js:591:32)
at ReactDOMComponent.Mixin.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactDOMComponent.js:479:29)
at Object.ReactReconciler.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactReconciler.js:37:35)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (C:\sports-whole-page\node_modules\react\lib\ReactMultiChild.js:241:44)
at ReactDOMComponent.Mixin._createContentMarkup (C:\sports-whole-page\node_modules\react\lib\ReactDOMComponent.js:591:32)
at ReactDOMComponent.Mixin.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactDOMComponent.js:479:29)
at Object.ReactReconciler.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactReconciler.js:37:35)
at [object Object].ReactCompositeComponentMixin.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactCompositeComponent.js:225:34)
at [object Object].wrapper [as mountComponent] (C:\sports-whole-page\node_modules\react\lib\ReactPerf.js:66:21)
at Object.ReactReconciler.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactReconciler.js:37:35)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (C:\sports-whole-page\node_modules\react\lib\ReactMultiChild.js:241:44)
at ReactDOMComponent.Mixin._createContentMarkup (C:\sports-whole-page\node_modules\react\lib\ReactDOMComponent.js:591:32)
at ReactDOMComponent.Mixin.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactDOMComponent.js:479:29)
at Object.ReactReconciler.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactReconciler.js:37:35)
at [object Object].ReactCompositeComponentMixin.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactCompositeComponent.js:225:34)
at [object Object].wrapper [as mountComponent] (C:\sports-whole-page\node_modules\react\lib\ReactPerf.js:66:21)
at Object.ReactReconciler.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactReconciler.js:37:35)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (C:\sports-whole-page\node_modules\react\lib\ReactMultiChild.js:241:44)
at ReactDOMComponent.Mixin._createContentMarkup (C:\sports-whole-page\node_modules\react\lib\ReactDOMComponent.js:591:32)
at ReactDOMComponent.Mixin.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactDOMComponent.js:479:29)
at Object.ReactReconciler.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactReconciler.js:37:35)
at [object Object].ReactCompositeComponentMixin.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactCompositeComponent.js:225:34)
at [object Object].wrapper [as mountComponent] (C:\sports-whole-page\node_modules\react\lib\ReactPerf.js:66:21)
at Object.ReactReconciler.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactReconciler.js:37:35)
at [object Object].ReactCompositeComponentMixin.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactCompositeComponent.js:225:34)
at [object Object].wrapper [as mountComponent] (C:\sports-whole-page\node_modules\react\lib\ReactPerf.js:66:21)
at Object.ReactReconciler.mountComponent (C:\sports-whole-page\node_modules\react\lib\ReactReconciler.js:37:35)
at mountComponentIntoNode (C:\sports-whole-page\node_modules\react\lib\ReactMount.js:266:32)
at ReactReconcileTransaction.Mixin.perform (C:\sports-whole-page\node_modules\react\lib\Transaction.js:136:20)
at batchedMountComponentIntoNode (C:\sports-whole-page\node_modules\react\lib\ReactMount.js:282:15)
at ReactDefaultBatchingStrategyTransaction.Mixin.perform (C:\sports-whole-page\node_modules\react\lib\Transaction.js:136:20)
at Object.ReactDefaultBatchingStrategy.batchedUpdates (C:\sports-whole-page\node_modules\react\lib\ReactDefaultBatchingStrategy.js:62:19)
at Object.batchedUpdates (C:\sports-whole-page\node_modules\react\lib\ReactUpdates.js:94:20)
at Object.ReactMount._renderNewRootComponent (C:\sports-whole-page\node_modules\react\lib\ReactMount.js:476:18)
at Object.wrapper [as _renderNewRootComponent] (C:\sports-whole-page\node_modules\react\lib\ReactPerf.js:66:21)
at Object.ReactMount._renderSubtreeIntoContainer (C:\sports-whole-page\node_modules\react\lib\ReactMount.js:550:32)
at Object.ReactMount.render (C:\sports-whole-page\node_modules\react\lib\ReactMount.js:570:23)
at Object.wrapper [as render] (C:\sports-whole-page\node_modules\react\lib\ReactPerf.js:66:21)
at Object.ReactTestUtils.renderIntoDocument (C:\sports-whole-page\node_modules\react\lib\ReactTestUtils.js:76:21)
at Context.<anonymous> (C:/codebase/sports-whole-page/test/components/sports-top-portion/sports-top-portion-unit-tests.js:28:41)
at callFn (C:\sports-whole-page\node_modules\mocha\lib\runnable.js:286:21)
at Test.Runnable.run (C:\sports-whole-page\node_modules\mocha\lib\runnable.js:279:7)
at Runner.runTest (C:\sports-whole-page\node_modules\mocha\lib\runner.js:421:10)
at C:\sports-whole-page\node_modules\mocha\lib\runner.js:528:12
at next (C:\sports-whole-page\node_modules\mocha\lib\runner.js:341:14)
at C:\sports-whole-page\node_modules\mocha\lib\runner.js:351:7
at next (C:\sports-whole-page\node_modules\mocha\lib\runner.js:283:14)
at Immediate._onImmediate (C:\sports-whole-page\node_modules\mocha\lib\runner.js:319:5)
let SportsTopPortion = connect(mapStateToProps)(SomeOtherComponent)
. La réponse la plus simple est de tester cet autre composant, pas le composant renvoyé parconnect
.searchComponent = <SportsDatabase sportsWholeFramework="desktop" />;
. C'est le composant connecté qui attend un magasin et une rupture. Donc, deux nouvelles suggestions: soit ne faites que le rendu superficiel de SportsTopPane, soit utilisez une bibliothèque comme Enzyme pour tester. Voir airbnb.io/enzyme/docs/api/ReactWrapper/setContext.html .Solution possible qui a fonctionné pour moi avec plaisanterie
la source
Comme le suggèrent les documents officiels de redux, mieux vaut également exporter le composant non connecté.
Afin de pouvoir tester le composant App lui-même sans avoir à traiter avec le décorateur, nous vous recommandons d'exporter également le composant non décoré:
Étant donné que l'exportation par défaut est toujours le composant décoré, l'instruction d'importation illustrée ci-dessus fonctionnera comme avant, vous n'aurez donc pas à modifier le code de votre application. Cependant, vous pouvez maintenant importer les composants d'application non décorés dans votre fichier de test comme ceci:
Et si vous avez besoin des deux:
Dans l'application elle-même, vous l'importeriez toujours normalement:
Vous utiliseriez uniquement l'exportation nommée pour les tests.
la source
Lorsque nous mettons en place une application react-redux, nous devrions nous attendre à voir une structure où en haut nous avons la
Provider
balise qui a une instance d'un magasin redux.Cette
Provider
balise rend ensuite votre composant parent, appelons-le leApp
composant qui à son tour rend tous les autres composants à l'intérieur de l'application.Voici la partie clé, lorsque nous enveloppons un composant avec la
connect()
fonction, cetteconnect()
fonction s'attend à voir un composant parent dans la hiérarchie qui a laProvider
balise.Ainsi, l'instance dans laquelle vous mettez la
connect()
fonction là-dedans, elle recherchera la hiérarchie et essaiera de trouver leProvider
.C'est ce que vous voulez faire, mais dans votre environnement de test, ce flux est en panne.
Pourquoi?
Pourquoi?
Lorsque nous revenons au fichier de test de sportsDatabase supposé, vous devez être le composant sportsDatabase par lui-même et ensuite essayer de rendre ce composant par lui-même de manière isolée.
Donc, essentiellement, ce que vous faites à l'intérieur de ce fichier de test consiste simplement à prendre ce composant et à le jeter dans la nature et il n'a aucun lien avec l'un
Provider
ou le stockage au-dessus et c'est pourquoi vous voyez ce message.Il n'y a pas de magasin ou de
Provider
balise dans le contexte ou l'accessoire de ce composant et le composant renvoie donc une erreur car il souhaite voir uneProvider
balise ou un magasin dans sa hiérarchie parent.Voilà donc ce que signifie cette erreur.
la source
dans mon cas juste
shallow(<Login />, { context: { store } });
la source
juste faire cette importation {shallow, mount} depuis "enzyme";
la source
Pour moi, c'était un problème d'importation, j'espère que cela aide. L'importation par défaut par WebStorm était incorrecte.
remplacer
avec
la source
Cela m'est arrivé lors de ma mise à niveau. J'ai dû rétrograder.
react-redux ^ 5.0.6 → ^ 7.1.3
la source
à la fin de votre Index.js devez ajouter ce code:
la source