рдЬрдм рдореИрдВ рдкрд░реАрдХреНрд╖рд╛ рд▓рд┐рдЦрддрд╛ рд╣реВрдВ рддреЛ рдореБрдЭреЗ рдорд┐рд▓рддрд╛ рд╣реИ
рд▓реЗрдЦрди рддреНрд░реБрдЯрд┐: рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреА рд╕рдВрдкрддреНрддрд┐ 'рддреИрдпрд╛рд░ рд╕реНрдЯрд╛рдЗрд▓' рдкрдврд╝рд╛ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛
рдореЗрд░рд╛ Component
рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ
import React, {PropTypes} from 'react';
import TransactionListRow from './TransactionListRow';
import {Table, TableBody, TableHeader, TableHeaderColumn, TableRow} from 'material-ui/Table';
const TransactionList = ({transactions}) => {
return (
<Table>
<TableHeader displaySelectAll={false}>
<TableRow>
<TableHeaderColumn>Name</TableHeaderColumn>
<TableHeaderColumn>Amount</TableHeaderColumn>
<TableHeaderColumn>Transaction</TableHeaderColumn>
<TableHeaderColumn>Category</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody>
{transactions.map(transaction =>
<TransactionListRow key={transaction.id} transaction={transaction}/>
)}
</TableBody>
</Table>
);
};
TransactionList.propTypes = {
transactions: PropTypes.array.isRequired
};
export default TransactionList;
рдореЗрд░рд╛ рдЯреЗрд╕реНрдЯ рджрд┐рдЦрддрд╛ рд╣реИ
import expect from 'expect';
import React from 'react';
import {mount} from 'enzyme';
import TransactionList from './TransactionList';
import TableHeaderColumn from 'material-ui/Table';
describe("<TransactionList />", ()=> {
it('renders four <TableHeaderColumn /> components', () => {
const wrapper = mount(<TransactionList transactions={[]}/>);
expect(wrapper.find(TableHeaderColumn)).to.have.length(4);
});
});
рдореЗрд░рд╛ index.js
(рдЬреЛ рдореЗрд░реА рд╕рдордЭ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдирд╣реАрдВ рд╣реИ) рд╣реИ
/*eslint-disable import/default */
import 'babel-polyfill';
import React from 'react';
import {render} from 'react-dom';
import configureStore from './store/configureStore.prod';
import {Provider} from 'react-redux';
import {Router, browserHistory} from 'react-router';
import routes from './routes';
import {loadAuthors} from './actions/authorActions';
import {loadCourses} from './actions/courseActions';
import './styles/styles.css'; //Webpack can import CSS files too!
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import '../node_modules/toastr/build/toastr.min.css';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
const store = configureStore();
store.dispatch(loadCourses());
store.dispatch(loadAuthors());
render(
<MuiThemeProvider muiTheme={getMuiTheme()}>
<Provider store={store}>
<Router history={browserHistory} routes={routes}/>
</Provider>
</MuiThemeProvider>,
document.getElementById('app')
);
рдЬрдм рдореИрдВ npm test:watch
рдЪрд▓рд╛рддрд╛ рд╣реВрдВ, рддреЛ рдореИрдВ рджреЗрдЦрддрд╛ рд╣реВрдВ
<TransactionList /> renders four <TableHeaderColumn /> components:
TypeError: Cannot read property 'prepareStyles' of undefined
at Table.render (node_modules/material-ui/Table/Table.js:155:48)
at ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (node_modules/react/lib/ReactCompositeComponent.js:687:34)
at ReactCompositeComponentMixin._renderValidatedComponent (node_modules/react/lib/ReactCompositeComponent.js:707:32)
at wrapper [as _renderValidatedComponent] (node_modules/react/lib/ReactPerf.js:66:21)
at ReactCompositeComponentMixin.performInitialMount (node_modules/react/lib/ReactCompositeComponent.js:291:30)
at ReactCompositeComponentMixin.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:222:21)
at wrapper [as mountComponent] (node_modules/react/lib/ReactPerf.js:66:21)
at Object.ReactReconciler.mountComponent (node_modules/react/lib/ReactReconciler.js:39:35)
at ReactCompositeComponentMixin.performInitialMount (node_modules/react/lib/ReactCompositeComponent.js:297:34)
at ReactCompositeComponentMixin.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:222:21)
at wrapper [as mountComponent] (node_modules/react/lib/ReactPerf.js:66:21)
at Object.ReactReconciler.mountComponent (node_modules/react/lib/ReactReconciler.js:39:35)
at ReactCompositeComponentMixin.performInitialMount (node_modules/react/lib/ReactCompositeComponent.js:297:34)
at ReactCompositeComponentMixin.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:222:21)
at wrapper [as mountComponent] (node_modules/react/lib/ReactPerf.js:66:21)
at Object.ReactReconciler.mountComponent (node_modules/react/lib/ReactReconciler.js:39:35)
at ReactCompositeComponentMixin.performInitialMount (node_modules/react/lib/ReactCompositeComponent.js:297:34)
at ReactCompositeComponentMixin.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:222:21)
at wrapper [as mountComponent] (node_modules/react/lib/ReactPerf.js:66:21)
at Object.ReactReconciler.mountComponent (node_modules/react/lib/ReactReconciler.js:39:35)
at mountComponentIntoNode (node_modules/react/lib/ReactMount.js:103:32)
at ReactReconcileTransaction.Mixin.perform (node_modules/react/lib/Transaction.js:136:20)
at batchedMountComponentIntoNode (node_modules/react/lib/ReactMount.js:124:15)
at ReactDefaultBatchingStrategyTransaction.Mixin.perform (node_modules/react/lib/Transaction.js:136:20)
at Object.ReactDefaultBatchingStrategy.batchedUpdates (node_modules/react/lib/ReactDefaultBatchingStrategy.js:63:19)
at Object.batchedUpdates (node_modules/react/lib/ReactUpdates.js:97:20)
at Object.ReactMount._renderNewRootComponent (node_modules/react/lib/ReactMount.js:277:18)
at Object.wrapper [as _renderNewRootComponent] (node_modules/react/lib/ReactPerf.js:66:21)
at Object.ReactMount._renderSubtreeIntoContainer (node_modules/react/lib/ReactMount.js:354:32)
at Object.ReactMount.render (node_modules/react/lib/ReactMount.js:374:23)
at Object.wrapper [as render] (node_modules/react/lib/ReactPerf.js:66:21)
at Object.ReactTestUtils.renderIntoDocument (node_modules/react/lib/ReactTestUtils.js:78:21)
at renderWithOptions (node_modules/enzyme/build/react-compat.js:175:26)
at new ReactWrapper (node_modules/enzyme/build/ReactWrapper.js:87:59)
at mount (node_modules/enzyme/build/mount.js:21:10)
at Context.<anonymous> (TransactionList.test.js:9:21)
рдореЗрд░реА рдирд┐рд░реНрднрд░рддрд╛рдПрдБ рд╣реИрдВ
"react": "15.0.2",
"react-tap-event-plugin": "^1.0.0",
"material-ui": "0.15.4"
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ https://github.com/callemall/material-ui/issues/4021 рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ
TL; DR : рдкрд░реАрдХреНрд╖рдг рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ рдШрдЯрдХ рдХреЛ <MuiThemeProvider />
рдпрд╛ https://github.com/callemall/material-ui/issues/4021#issuecomment -210998829 рдореЗрдВ рд▓рдкреЗрдЯрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред
рдХреНрдпрд╛ рдЖрдкрдХрд╛ рдорддрд▓рдм рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЬреИрд╕рд╛ рдХреБрдЫ рдерд╛?
import expect from 'expect';
import React from 'react';
import {mount} from 'enzyme';
import TransactionList from './TransactionList';
import {TableHeaderColumn} from 'material-ui/Table';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
function setup() {
return mount(
<MuiThemeProvider>
<TransactionList transactions={[]}/>
</MuiThemeProvider>, {
getChildContext() {
return {muiTheme: getMuiTheme()};
},
childContextTypes: {muiTheme: React.PropTypes.object}
});
}
describe("<TransactionList />", ()=> {
it('renders four <TableHeaderColumn /> components', () => {
const wrapper = mount(<TransactionList transactions={[]}/>);
expect(wrapper.find(TableHeaderColumn)).to.have.length(4);
});
});
рдореИрдВрдиреЗ рдпрд╣ рднреА рдХреЛрд╢рд┐рд╢ рдХреА, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рджреЗрдЦреЗрдВ
1) <TransactionList /> renders four <TableHeaderColumn /> components:
TypeError: Cannot read property 'prepareStyles' of undefined
at Table.render (node_modules/material-ui/Table/Table.js:155:48)
at node_modules/react/lib/ReactCompositeComponent.js:793:21
at measureLifeCyclePerf (node_modules/react/lib/ReactCompositeComponent.js:74:12)
at ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (node_modules/react/lib/ReactCompositeComponent.js:792:27)
at ReactCompositeComponentMixin._renderValidatedComponent (node_modules/react/lib/ReactCompositeComponent.js:819:34)
at ReactCompositeComponentMixin.performInitialMount (node_modules/react/lib/ReactCompositeComponent.js:361:30)
at ReactCompositeComponentMixin.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:257:21)
at Object.ReactReconciler.mountComponent (node_modules/react/lib/ReactReconciler.js:47:35)
at ReactCompositeComponentMixin.performInitialMount (node_modules/react/lib/ReactCompositeComponent.js:370:34)
at ReactCompositeComponentMixin.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:257:21)
at Object.ReactReconciler.mountComponent (node_modules/react/lib/ReactReconciler.js:47:35)
at ReactCompositeComponentMixin.performInitialMount (node_modules/react/lib/ReactCompositeComponent.js:370:34)
at ReactCompositeComponentMixin.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:257:21)
at Object.ReactReconciler.mountComponent (node_modules/react/lib/ReactReconciler.js:47:35)
at ReactCompositeComponentMixin.performInitialMount (node_modules/react/lib/ReactCompositeComponent.js:370:34)
at ReactCompositeComponentMixin.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:257:21)
at Object.ReactReconciler.mountComponent (node_modules/react/lib/ReactReconciler.js:47:35)
at mountComponentIntoNode (node_modules/react/lib/ReactMount.js:105:32)
at ReactReconcileTransaction.Mixin.perform (node_modules/react/lib/Transaction.js:138:20)
at batchedMountComponentIntoNode (node_modules/react/lib/ReactMount.js:127:15)
at ReactDefaultBatchingStrategyTransaction.Mixin.perform (node_modules/react/lib/Transaction.js:138:20)
at Object.ReactDefaultBatchingStrategy.batchedUpdates (node_modules/react/lib/ReactDefaultBatchingStrategy.js:63:19)
at Object.batchedUpdates (node_modules/react/lib/ReactUpdates.js:98:20)
at Object.ReactMount._renderNewRootComponent (node_modules/react/lib/ReactMount.js:321:18)
at Object.ReactMount._renderSubtreeIntoContainer (node_modules/react/lib/ReactMount.js:402:32)
at Object.ReactMount.render (node_modules/react/lib/ReactMount.js:423:23)
at Object.ReactTestUtils.renderIntoDocument (node_modules/react/lib/ReactTestUtils.js:84:21)
at renderWithOptions (node_modules/enzyme/build/react-compat.js:175:26)
at new ReactWrapper (node_modules/enzyme/build/ReactWrapper.js:87:59)
at mount (node_modules/enzyme/build/mount.js:21:10)
at Context.<anonymous> (TransactionList.test.js:24:20)
рдореБрдЭреЗ рдмрддрд╛рдПрдВ рдХрд┐ рдореИрдВ рдХреНрдпрд╛ рдЧрд▓рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдБ?
рд╕рд╛рдордЧреНрд░реА-рдпреВрдЖрдИ рдореЗрдВ рдЬреЛ рдкрд░реАрдХреНрд╖рдг рдореИрдВ рджреЗрдЦрддрд╛ рд╣реВрдВ, рдЙрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдореИрдВрдиреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрд╢рд┐рд╢ рдХреА рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рд╡рд╣реА рдкрд░рд┐рдгрд╛рдо:
import expect from 'expect';
import React from 'react';
import {mount} from 'enzyme';
import TransactionList from './TransactionList';
import {TableHeaderColumn} from 'material-ui/Table';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
describe("<TransactionList />", ()=> {
const muiTheme = getMuiTheme();
const mountWithContext = (node) => mount(node, {context: {muiTheme}});
it('renders four <TableHeaderColumn /> components', () => {
const wrapper = mountWithContext(<TransactionList transactions={[]}/>);
expect(wrapper.find(TableHeaderColumn)).to.have.length(4);
});
@рд╣рд┐рдорд╛рдВрд╢реБ : рдХреНрдпрд╛ рдЖрдк рдПрдХ рдкреЗрди рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдореИрдВ рдЗрд╕реЗ рджреЗрдЦ рд╕рдХреВрдВ ?
@lucasbento , рдореИрдВ рдХрд▓рдо https://github.com/101bits/pluralsight-react рджреНрд╡рд╛рд░рд╛ рдЕрдкрд▓реЛрдб рдХрд┐рдпрд╛
рдкреНрд░рдЬрдирди рдХреЗ рдЪрд░рдг
- npm install
- npm start -s
рдЕрдЧрд░ рдореБрдЭреЗ рдХреБрдЫ рдпрд╛рдж рдЖрдпрд╛ рддреЛ рдореБрдЭреЗ рдмрддрд╛рдПрдВ, рдзрдиреНрдпрд╡рд╛рдж
рд╣реЗ @рд╣рд┐рдорд╛рдВрд╢реБ ,
рдЖрдкрдХреА рд╕рдорд╕реНрдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдореИрдВ рдХрднреА рднреА context
рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди...
рдореИрдВрдиреЗ рджреЗрдЦрд╛ рдХрд┐ this
рдЖрдкрдХреЗ рдШрдЯрдХ рдореЗрдВ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдерд╛, рдореИрдВрдиреЗ рдЗрд╕реЗ рдПрдХ рд╕реНрдЯреЗрдЯрд▓реЗрд╕ рдШрдЯрдХ рдХреЗ рдмрдЬрд╛рдп рдПрдХ рд╡рд░реНрдЧ рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдФрд░ рдЬрд╛рджреВ рдХреА рддрд░рд╣ this
рдЙрдкрд▓рдмреНрдз рд╣реЛ рдЧрдпрд╛:
import React, {Component} from 'react';
import TransactionListRow from './TransactionListRow';
import {Table, TableBody, TableHeader, TableHeaderColumn, TableRow} from 'material-ui/Table';
class TransactionList extends Component {
render() {
const { transactions } = this.props;
return (
<Table>
<TableHeader displaySelectAll={false}>
<TableRow>
<TableHeaderColumn>Name</TableHeaderColumn>
<TableHeaderColumn>Amount</TableHeaderColumn>
<TableHeaderColumn>Transaction</TableHeaderColumn>
<TableHeaderColumn>Category</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody>
{transactions.map(transaction =>
<TransactionListRow key={transaction.id} transaction={transaction}/>
)}
</TableBody>
</Table>
);
}
};
рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ _alot_ рдЖрдЬрд╝рдорд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
import { expect } from 'chai';
import React from 'react';
import { mount } from 'enzyme';
import TransactionList from './TransactionList';
import {TableHeaderColumn} from 'material-ui/Table';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
describe("<TransactionList />", ()=> {
const mountWithContext = (node) => mount(node, {
context: {
muiTheme: getMuiTheme(),
},
childContextTypes: {
muiTheme: React.PropTypes.object.isRequired,
}
});
it('renders five <TableHeaderColumn /> components', () => {
const wrapper = mount(<TransactionList transactions={[]}/>, {
context: {
muiTheme: getMuiTheme(),
},
childContextTypes: {
muiTheme: React.PropTypes.object.isRequired,
},
});
expect(wrapper.find(TableHeaderColumn)).to.have.length(5);
});
});
рдореИрдВ chai
рдмрдЬрд╛рдп expect
рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЖрдкрдХрд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ chai
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рдерд╛ред
рдореИрдВ рдЬреЗрд╕реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рджреГрдврд╝рддрд╛ рд╕реЗ рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд░рддрд╛ рд╣реВрдВ, рд╕реНрдиреИрдкрд╢реЙрдЯ рдкрд░реАрдХреНрд╖рдг рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред
рдореИрдВрдиреЗ <TableHeaderColumn />
рдХреЛ 4 рдХреЗ рдмрдЬрд╛рдп 5 рдореЗрдВ рднреА рдмрджрд▓ рджрд┐рдпрд╛, рднрд▓реЗ рд╣реА рдлрд╝рд╛рдЗрд▓ рдкрд░ 4 <TableHeaderColumn />
, рдПрдВрдЬрд╛рдЗрдо 5 рд▓реМрдЯрд╛рддрд╛ рд╣реИред ┬п_(уГД)_/┬п
рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░реЗрдЧрд╛!
рдореИрдВ рднреА рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдЗрд╕рдХрд╛ рд╕рдорд╛рдзрд╛рди рдЕрднреА рддрдХ рдирд╣реАрдВ рд╣реЛ рдкрд╛рдпрд╛ рд╣реИред
@ janoist1 : рдореИрдВрдиреЗ рдЬреЛ рднреЗрдЬрд╛ рд╣реИ, рдХреНрдпрд╛ рдЖрдкрдиреЗ рдЙрд╕реЗ
рдзрдиреНрдпрд╡рд╛рдж, рдФрд░ рд╣рд╛рдБ рдореИрдВрдиреЗ рдХрд┐рдпрд╛ред рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдпрд╣ рдЕрднреА рднреА рдПрдХ рдХрд╛рдордХрд╛рдЬ рд╣реИред рдпрд╣ shallow
рднреА рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдм рдореБрдЭреЗ рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рдореИрдВ find
рдЪрд╛рдЗрд▓реНрдб рдХрдВрдкреЛрдиреЗрдВрдЯреНрд╕ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░реЛрдк рд╕рд┐рд▓реЗрдХреНрдЯрд░ рдиреЗ рдХрд╛рдо рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рджрд┐рдпрд╛ рдерд╛ред рд╕реНрдЯреИрдХрдУрд╡рд░рдлреНрд▓реЛ рдкреНрд░рд╢реНрди
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВ рдпрд╣ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рдореБрдЭреЗ рдЕрдкрдиреЗ рдШрдЯрдХ рдХреЛ рд░рд┐рдПрдХреНрдЯ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
@ janoist1 рдЬрдм рдореИрдВ рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░рддрд╛ рд╣реВрдВ рддреЛ рдореБрдЭреЗ рдорд┐рд▓рддрд╛ рд╣реИ
Uncaught Exception: test/components/Foo/List/index.js
RangeError: Invalid string length
_combinedTickCallback (internal/process/next_tick.js:67:7)
process._tickCallback (internal/process/next_tick.js:98:9)
тЬЦ Test results were not received from test/components/Foo/List/index.js
рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдмрдВрдж рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдХреНрдпреЛрдВрдХрд┐ рдирд┐рд░реНрдорд╛рддрд╛ рдХреЗ рдкрд╛рд╕ рдХреЛрдИ рдЬрд╡рд╛рдм рдирд╣реАрдВ рд╣реИ, рдЕрдЧрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рдФрд░ рдкреНрд░рд╢реНрди рд╣реИрдВ рддреЛ рдХреГрдкрдпрд╛ stackoverflow.com рдкрд░ рдкреВрдЫреЗрдВред
@lucasbento рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рднреА рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдирд╣реАрдВред рдмрд▓реНрдХрд┐ next.js . рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореЗрд░реЗ рдРрдк рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЗ рд╕рдордп
рдмрд╕ рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдореИрдВрдиреЗ рдЖрдЦрд┐рд░реА рджрд┐рди рдмрд┐рддрд╛рдпрд╛ рд╣реИ рдпрд╛ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдбреАрдмрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИ - рдФрд░ рдЬрдм рдЙрддреНрддрд░ рдореЗрд░реЗ рд▓рд┐рдП рд╕реНрдкрд╖реНрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдерд╛, рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рдпрд╣ рдЙрд▓реНрд▓реЗрдЦ рдХрд░ рд╕рдХрддрд╛ рд╣реИ:
рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдРрдк рд╕реЗрдЯ рдЕрдк рд╣реИ рдЬреЛ рд╕рд░реНрд╡рд░рд╕рд╛рдЗрдб рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рд╕рд░реНрд╡рд░рд╕рд╛рдЗрдб рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯрд╕рд╛рдЗрдб рдРрдк рджреЛрдиреЛрдВ рдХреЛ <MuiThemeProvider>
рд▓рдкреЗрдЯрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИред
рдмрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореЛрдЪрд╛ рдХреЗ рд╕рд╛рде рдорд╛рдЙрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ jsdom рдЬреИрд╕рд╛ рдХреБрдЫ рдЪрд╛рд╣рд┐рдП рдпрд╛ рдЖрдкрдХреЛ document.createElement is not a function
рдорд┐рд▓реЗрдЧрд╛
рдпрд╣рд╛рдВ рд╕реЗрдЯрдЕрдк рджреЗрдЦреЗрдВ: https://github.com/airbnb/enzyme/blob/master/docs/guides/jsdom.md
рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдПрдХ рд╣реА рдореБрджреНрджреЗ рдХрд╛ рдЕрдиреБрднрд╡ рдХрд┐рдпрд╛ .. рдпрд╣ рдШрдЯрдХ рд╡рд░реНрдЧ рдХреЗ рдореЗрд░реЗ рдирд╛рдордХрд░рдг рдХрд╛ рдореБрджреНрджрд╛ рдерд╛ .. рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдШрдЯрдХ рд╡рд░реНрдЧрдирд╛рдо, рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдФрд░ рдЖрдпрд╛рдд рд╡рд┐рд╡рд░рдг рдХреЛ рдореБрдЦреНрдп рдРрдк рдШрдЯрдХ рдореЗрдВ рдирдП рдирд╛рдо рд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ рдФрд░ рдпрд╣ рдХрд╛рдо рдХрд░рдиреЗ рд▓рдЧрд╛ред
рдореБрдЭреЗ рднреА рдпрд╣реА рд╕рдорд╕реНрдпрд╛ рдереАред рдореЗрд░реА рд╕рдорд╕реНрдпрд╛ рдпрд╣ рдереА рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдХреНрд▓рд╛рд╕рдирд╛рдо рдХреЗ рдмрдЬрд╛рдп рдореЗрд░реЗ рдЬреЗрдПрд╕рдПрдХреНрд╕ рдбрд┐рд╡ рдореЗрдВ рд╕реЗ рдПрдХ рдореЗрдВ рдХреНрд▓рд╛рд╕ рдПрдЯреНрд░рд┐рдмреНрдпреВрдЯ рдерд╛
рдЖрдкрдХреЛ рдЕрдкрдиреА рддрд╛рд▓рд┐рдХрд╛ рдХреЛ MuiThemeProvider рдЯреИрдЧ рдореЗрдВ рд▓рдкреЗрдЯрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
https://stackoverflow.com/questions/39863436/typeerror-cannot-read-property-preparestyles-of-undefined рд╕рдорд╛рдзрд╛рди рд╣реИ
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ https://github.com/callemall/material-ui/issues/4021 рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ
TL; DR : рдкрд░реАрдХреНрд╖рдг рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ рдШрдЯрдХ рдХреЛ
<MuiThemeProvider />
рдпрд╛ https://github.com/callemall/material-ui/issues/4021#issuecomment -210998829 рдореЗрдВ рд▓рдкреЗрдЯрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред