Я использую Enzyme
to unit test мои компоненты React. Я понимаю, что для проверки сырого несвязанного компонента мне пришлось бы просто экспортировать его и протестировать (я сделал это). Мне удалось написать тест для подключенного компонента, но я действительно не уверен, правильно ли это, и что именно я хотел бы проверить для подключенного компонента.
Container.jsx
import {connect} from 'react-redux';
import Login from './Login.jsx';
import * as loginActions from './login.actions';
const mapStateToProps = state => ({
auth: state.auth
});
const mapDispatchToProps = dispatch => ({
loginUser: credentials => dispatch(loginActions.loginUser(credentials))
});
export default connect(mapStateToProps, mapDispatchToProps)(Login);
Container.test.js
import React from 'react';
import {Provider} from 'react-redux';
import {mount, shallow} from 'enzyme';
import {expect} from 'chai';
import LoginContainer from '../../src/login/login.container';
import Login from '../../src/login/Login';
describe('Container Login', () => {
it('should render the container component', () => {
const storeFake = state => ({
default: () => {
},
subscribe: () => {
},
dispatch: () => {
},
getState: () => ({ ...state })
});
const store = storeFake({
auth: {
sport: 'BASKETBALL'
}
});
const wrapper = mount(
<Provider store={store}>
<LoginContainer />
</Provider>
);
expect(wrapper.find(LoginContainer).length).to.equal(1);
const container = wrapper.find(LoginContainer);
expect(container.find(Login).length).to.equal(1);
expect(container.find(Login).props().auth).to.eql({ sport: 'BASKETBALL' });
});
});
Ответ 1
Это интересный вопрос.
Я обычно импортирую как контейнер, так и компонент для тестирования. Для тестирования контейнера я использую redux-mock-store
. Тестирование компонентов для тестирования асинхронных функций. Например, в вашем случае процесс входа - это асинхронная функция с использованием sinon
заглушек. Вот фрагмент того же самого,
import React from 'react';
import {Provider} from 'react-redux';
import {mount, shallow} from 'enzyme';
import {expect} from 'chai';
import LoginContainer from '../../src/login/login.container';
import Login from '../../src/login/Login';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { stub } from 'sinon';
const mockStore = configureMockStore([thunk]);
describe('Container Login', () => {
let store;
beforeEach(() => {
store = mockStore({
auth: {
sport: 'BASKETBALL',
},
});
});
it('should render the container component', () => {
const wrapper = mount(
<Provider store={store}>
<LoginContainer />
</Provider>
);
expect(wrapper.find(LoginContainer).length).to.equal(1);
const container = wrapper.find(LoginContainer);
expect(container.find(Login).length).to.equal(1);
expect(container.find(Login).props().auth).to.eql({ sport: 'BASKETBALL' });
});
it('should perform login', () => {
const loginStub = stub().withArgs({
username: 'abcd',
password: '1234',
});
const wrapper = mount(<Login
loginUser={loginStub}
/>);
wrapper.find('button').simulate('click');
expect(loginStub.callCount).to.equal(1);
});
});
Ответ 2
Как вы указали, способ, которым я обычно это делаю, - это экспортировать не подключенный компонент, а также проверить это.
то есть.
export {Login};
Вот пример. Источник компонента и источник тестов.
Для обернутого компонента я не создаю тестов для них, потому что мои сопоставления (mapStateToProps
и mapDispatchToProps
), как правило, очень просты. Если бы я хотел протестировать завернутый компонент, я бы просто тестировал эти карты. Таким образом, это то, что я бы выбрал для явного тестирования, а не для повторного тестирования всего компонента в завернутой форме.
Существует два способа тестирования этих функций. Один из способов - экспортировать функции внутри самого модуля.
то есть;.
export {mapStateToProps, mapDispatchToProps}
Я не большой поклонник этого, потому что я не хочу, чтобы другие модули в приложении обращались к ним. В моих тестах я иногда использую babel-plugin-rewire для доступа к переменным "in-scope", поэтому я бы сделал это в этой ситуации.
Это может выглядеть примерно так:
import {
Login, __Rewire__
}
const mapStateToProps = __Rewire__.__get__('mapStateToProps');
describe('mapStateToProps', () => { ... });