我正在使用Enzyme
对我的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' });
});
});
答案 0 :(得分:21)
这是一个有趣的问题。
我通常会导入容器和组件来进行测试。对于容器测试,我使用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);
});
});
答案 1 :(得分:3)
正如您所指出的,我通常这样做的方式是导出未连接的组件,并测试它。
即
export {Login};
这是一个例子。 Source of the component和source of the tests。
对于包装组件,我不会为这些组件创建测试,因为我的映射(mapStateToProps
和mapDispatchToProps
)通常非常简单。如果我想测试一个包装好的组件,我真的只是测试那些地图。所以我会选择明确测试,而不是以包装形式重新测试整个组件。
有两种方法可以测试这些功能。一种方法是导出模块本身的功能。
即;
export {mapStateToProps, mapDispatchToProps}
我不是这方面的忠实粉丝,因为我不希望应用中的其他模块访问它们。在我的测试中,我有时使用babel-plugin-rewire来访问&#34;范围内&#34;变量,这就是我在这种情况下会做的事情。
这看起来像是:
import {
Login, __Rewire__
}
const mapStateToProps = __Rewire__.__get__('mapStateToProps');
describe('mapStateToProps', () => { ... });
答案 2 :(得分:0)
如果遇到路由器问题,可以考虑将路由器库添加到测试文件中,例如:
import React from 'react';
import { Provider } from 'react-redux';
import { BrowserRouter as Router } from 'react-router-dom';
import { mount } from 'enzyme';
import ReadDots from './ReadDots';
const storeFake = state => ({
default: () => {
},
subscribe: () => {
},
dispatch: () => {
},
getState: () => ({ ...state })
});
const store = storeFake({
dot: {
dots: [
{
id: '1',
dot: 'test data',
cost: '100',
tag: 'pocket money'
}
]
}
});
describe('<ReadDots />', () => {
it('should render ReadDots component', () => {
const component = mount(
<Provider store={store}>
<Router>
<ReadDots />
</Router>
</Provider>
);
expect(component.length).toEqual(1);
});
});