Heim > Fragen und Antworten > Hauptteil
Weil in enzyme
没有维护并且不支持react 18+,所以我正在尝试将1750多个现有的单元测试迁移到react-testing-library
+ global-jsdom
来运行,这样我们的应用程序就可以继续运行最新版本的react。我们所有的测试都是使用mocha
、chai
、enzyme
编写的,我希望尽可能简单地迁移。换句话说,我绝不会在一个全新的框架如jest
mehr als 1750 Tests neu geschrieben wurden.
Ich versuche es gemäß react-testing-library
来对react组件进行单元测试的示例。如果我在使用React.createElement
时使用简单的元素,比如'div'
或'input'
zu verwenden und es funktioniert gut, aber wenn ich die Material-UI-Komponente verwende, erhalte ich die Fehlermeldung:
TypeError: Eigenschaft von Null kann nicht gelesen werden (lesen Sie „registriert“) In C:UsersuserDocumentsprojectnode_modules@emotionstyledbasedistemotion-styled-base.cjs.dev.js:143:53
Der obige Fehler tritt in der Komponente <Styled(div)> auf:
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)Erwägen Sie das Hinzufügen von Fehlergrenzen zu Ihrem Baum, um das Fehlerbehandlungsverhalten anzupassen. Besuchen Sie https://reactjs.org/link/error-boundaries, um mehr über Fehlergrenzen zu erfahren. Der Stack-Trace ist nicht genau, aber er schlägt fehl, wenn ich versuche,
h(Box, {},...)
(MUI-Element erstellen) auszuführen.
Das versuche ich zu rendern 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;
Das ist der Mokka-Unit-Test:
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); }); });
Es fühlt sich an, als würde mir ein Kontext fehlen, damit die MUI-Komponente gerendert werden kann, aber ich kann nicht herausfinden, was das ist oder ob das tatsächlich das Problem ist. Für diesen spezifischen Fehler gibt es nicht viele Google-Ergebnisse. Irgendwelche Ideen?
P粉7454121162024-01-17 00:03:09
根据MUI库的依赖关系,我发现它们在一些渲染过程中使用了@emotion/react和@emotion/styled,这似乎是MUI v5的一个问题,他们改变了缓存对象并意外地删除了@emotion/react提供的缓存对象,这导致了TypeError: Cannot read property 'registered' of undefined
的错误,因为他们没有在新的缓存中添加cache.registered
。
解决方案:我通过在我的组件中包装@emotion/react提供者({my component})来解决了这个问题。你可以尝试按照@emotion.react提供的示例进行操作:https://emotion.sh/docs/cache-provider
还要确保正确安装了来自@emotion/react的依赖项,可以运行以下命令:npm install --save @emotion/react
或yarn add @emotion/react
代码应该如下所示:
这是使用更熟悉的JSX语法的dummyComponent.js:
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;
这是mocha单元测试:
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); }); });
请注意,我在测试用例中还使用了一些JSX语法和const { expect } = require('chai');
,这使我可以使用should
和从chai链式调用其他函数。