Как протестировать компонент с состоянием и редукс-соединением, используя response-i18next
Я нахожусь в ситуации, когда мне нужно выполнить модульное тестирование компонента с отслеживанием состояния, который также связан с избыточным хранилищем, для отправки событий. Я использую Jest и Enzyme.
Я пробовал различные примеры, доступные в документации: https://react.i18next.com/misc/testing
Ни один из примеров не покрывает случай использования redux-connect.
Рассмотрим следующий компонент реагирования в псевдокоде:
// ../MyComponent.js
import React, { Component } from 'react';
import { bindActionCreators, compose } from 'redux';
import { connect } from 'react-redux';
import { withNamespaces } from 'react-i18next';
class MyComponent extends Component {
constructor(props) {
super(props);
// init state…
}
// Code body…
}
// Using compose from Redux lib
export default compose(
connect(null, mapDispatchToProps),
withNamespaces('myNamespace'),
)(MyComponent);
Модульный тест:
// ../__tests__/MyComponent.test.js
import React from 'react';
import { shallow, mount } from 'enzyme';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import { I18nextProvider } from 'react-i18next';
import i18n from '../../i18nForTests';
import reducers from '../../reducers';
import MyComponent from '../MyComponent';
const createStoreWithMiddleware = applyMiddleware()(createStore);
let MyComponentForTest = (
<Provider store={createStoreWithMiddleware(reducers)}>
<I18nextProvider i18n={i18n}>
<MyComponent />
</I18nextProvider>
</Provider>
);
describe('MyComponent state', () => {
let myPage;
test('init', () => {
myPage = shallow(MyComponentForTest); <-- Not getting the actual component.
});
});
Используя следующие зависимости
"react": "^16.6.1",
"react-app-polyfill": "^0.1.3",
"react-dev-utils": "^6.0.5",
"react-dom": "^16.6.1",
"react-i18next": "^8.3.8",
"react-inlinesvg": "^0.8.2",
"react-redux": "^5.1.1",
"redux": "^4.0.1",
"i18next": "^12.1.0",
"identity-obj-proxy": "3.0.0",
"jest": "23.6.0",
"jest-pnp-resolver": "1.0.1",
"jest-resolve": "23.6.0",
"webpack": "4.19.1",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.7.0",
Я не могу получить реальный компонент при использовании функции мелкой или монтирования из Enzyme. Вместо этого я получаю упакованные контексты, либо провайдера, объект контекста или что-то еще - это означает, что я не могу проверить компонент.
Для пояснения - это то, как выглядел мой модульный тест перед добавлением библиотеки activ-i18next…
экспорт в MyComponent.js
export default connect(null, mapDispatchToProps)(MyComponent); <-- Note, not using compose as it is not needed.
Модульный тест, MyComponent.test.js
let MyComponentForTest = <MyComponent store={createStoreWithMiddleware(reducers)} />;
describe(’MyComponent', () => {
describe('initially', () => {
let myPage;
test('init', () => {
myPage = shallow(MyComponentForTest).dive(); <-- Note, using dive(), to get the component.
console.log('*** myPage: ', myPage.debug());
});
});
В терминале:
<MyComponent store={{...}} redirectPage={[Function]} />
Таким образом, я 'ясно могу получить компонент, когда не использую реагировать-i18next.
Я думаю, что, по крайней мере, часть проблемы в том, что withNamespaces() не возвращает компонент, вместо этого он оборачивает его в какой-то объект Context-объекта...
1 ответ
Ну, мое предложение здесь будет экспортировать MyComponent
и передать его издевательскому состоянию в качестве реквизита. Что-то вроде этого:
const mockedState = {
...state data you want to pass
}
const MyComponentForTest = <MyComponent state={mockedState} />
describe('MyComponent state', () => {
let myPage;
test('init', () => {
myPage = shallow(MyComponentForTest);
});
});
Весь смысл в том, что ваш компонент ведет себя в определенном состоянии, которое вы хотите проверить здесь. Это должно служить цели здесь.