Maison  >  Questions et réponses  >  le corps du texte

Une erreur de test Mocha est générée lors du rendu du composant MUI dans jsdom à l'aide de la bibliothèque de tests React

Parce que plus de 1750 tests ont été réécrits en enzyme没有维护并且不支持react 18+,所以我正在尝试将1750多个现有的单元测试迁移到react-testing-library + global-jsdom来运行,这样我们的应用程序就可以继续运行最新版本的react。我们所有的测试都是使用mochachaienzyme编写的,我希望尽可能简单地迁移。换句话说,我绝不会在一个全新的框架如jest.

J'essaie de l'utiliser selon react-testing-library来对react组件进行单元测试的示例。如果我在使用React.createElement时使用简单的元素,比如'div''input' et cela fonctionne bien, mais lorsque j'utilise le composant matériel de l'interface utilisateur, j'obtiens l'erreur :

TypeError : Impossible de lire la propriété null (lire "enregistré") Dans C:UsersuserDocumentsprojectnode_modules@emotionstyledbasedistemotion-styled-base.cjs.dev.js:143:53

L'erreur ci-dessus se produit dans le composant <Styled(div)>

at C:\Users\user\Documents\project\node_modules\@emotion\react\dist\emotion-element-b63ca7c6.cjs.dev.js:43:23
at Box (C:\Users\user\Documents\project\node_modules\@mui\system\createBox.js:29:41)
at DummyComponent (C:\Users\user\Documents\project\act-app\src\component\page\dummyComponent.js:2:346)

Envisagez d'ajouter des limites d'erreur à votre arborescence pour personnaliser le comportement de gestion des erreurs. Visitez https://reactjs.org/link/error-boundaries pour en savoir plus sur les limites d'erreur. La trace de la pile n'est pas précise, mais elle échoue lorsque j'essaie de faire

(créer un élément mui). h(Box, {},...)

Voici ce que j'essaie de restituer

 : dummyComponent.js

const { Box } = require('@mui/material');
const React = require('react');
const h = React.createElement;

const DummyComponent = (props) => {
  const { children } = props;
  const [showChild, setShowChild] = React.useState(false);
  return (
    h(Box, {},
      h('label', { htmlFor: 'toggle' }, 'Show/Hide'),
      h('input', { id: 'toggle', type: 'checkbox', onChange: (e) => setShowChild(e.target.checked), checked: showChild }),
      showChild && children)
  );
};

module.exports = DummyComponent;

Voici le test unitaire moka :

const React = require('react');
const { render, fireEvent } = require('@testing-library/react');
const h = React.createElement;

const DummyComponent = require('./dummyComponent');

describe('pageCenter', function () {
  before(function () {
    this.jsdom = require('global-jsdom')();
  });

  after(function () {
    this.jsdom();
  });

  it('should render', function () {
    const w = render(h(DummyComponent, {}, 'Hi!'));
    w.queryAllByText('Hi!').should.have.length(0);
    fireEvent.click(w.getByLabelText('Show/Hide'));
    w.queryAllByText('Hi!').should.have.length(1);
  });
});

J'ai l'impression qu'il me manque un peu de contexte pour permettre au composant MUI de s'afficher, mais je n'arrive pas à comprendre quoi, ni si c'est réellement le problème. Il n'y a pas beaucoup de résultats Google pour cette erreur spécifique. Des idées?

P粉946437474P粉946437474299 Il y a quelques jours450

répondre à tous(1)je répondrai

  • P粉745412116

    P粉7454121162024-01-17 00:03:09

    Selon les dépendances de la bibliothèque MUI, j'ai découvert qu'ils utilisaient @emotion/react et @emotion/styled dans certains processus de rendu, cela semble être un problème avec MUI v5, ils modifient l'objet cache et le suppriment de manière inattendue L'objet cache fourni par @emotion/react a abouti à TypeError: Cannot read property 'registered' of undefined的错误,因为他们没有在新的缓存中添加cache.registered.

    Solution : j'ai résolu ce problème en encapsulant le fournisseur @emotion/react ({mon composant}) dans mon composant. Vous pouvez essayer de suivre l'exemple fourni par @emotion.react : https://emotion.sh/docs/cache-provider

    Assurez-vous également que les dépendances de @emotion/react sont correctement installées en exécutant la commande suivante : npm install --save @emotion/reactyarn add @emotion/react

    Le code devrait ressembler à ceci :

    Voici dummyComponent.js utilisant une syntaxe JSX plus familière :

    const React = require('react');
    const { Box } = require('@mui/material');
    
    const DummyComponent = (props) => {
      const { children } = props;
      const [showChild, setShowChild] = React.useState(false);
    
      return (
        <Box>
          <label htmlFor="toggle">Show/Hide</label>
          <input
            id="toggle"
            type="checkbox"
            onChange={(e) => setShowChild(e.target.checked)}
            checked={showChild}
          />
          {showChild && children}
        </Box>
      );
    };
    
    export default DummyComponent;

    Voici le test unitaire moka :

    const React = require('react');
    const { expect } = require('chai');
    const { render, fireEvent } = require('@testing-library/react');
    const createCache = require("@emotion/cache");
    
    const DummyComponent = require('./dummyComponent');
    
    describe('pageCenter', function () {
      before(function () {
        this.jsdom = require('global-jsdom')();
      });
    
      after(function () {
        this.jsdom();
      });
      
      const myCache = createCache({
       key: 'my-prefix-key'
      });
    
      it('should render', function () {
        const { queryAllByText, getByLabelText } = render(
          <CacheProvider value={myCache}>          
            <DummyComponent>Hi!</DummyComponent>
          </CacheProvider>
        );
    
        expect(queryAllByText('Hi!')).should.have.length(0);
        fireEvent.click(getByLabelText('Show/Hide'));
        expect(queryAllByText('Hi!')).should.have.length(1);
      });
    });

    Veuillez noter que j'utilise également une certaine syntaxe JSX dans le scénario de test const { expect } = require('chai');,这使我可以使用should et que j'appelle en chaîne d'autres fonctions depuis chai.

    répondre
    0
  • Annulerrépondre