我有一个像这样的项目结构:
app/
global/
styles/
components/
scenes/
Home/
actions.js
constants.js
index.jsx
reducer.js
sagas.js
styles.styl
index.spec.jsx
some-other-scene/
actions.js
constants.js
index.jsx
reducer.js
sagas.js
styles.styl
index.spec.jsx
所以我对这种结构的单元测试没有问题,但是我对如何进行结构化集成测试感到很困惑。对于我的单元测试,我将每个场景组件导出为一个类
export class SomeComponent extends Component {}
并作为Redux连接的组件
export default connect(
mapStateToProps,
mapDispatchToProps
)(SomeComponent)
因此,对于第一个导出样式(类),我对其进行单元测试,但是对于第二种方式(连接组件方式),我不确定如何具体实现此方法,如何在react / redux中进行集成测试。我已经在互联网上搜索了有关此内容的信息,但没有找到与之接近的信息。
所以:
如果是#1,那我该如何通过React Router测试路由?
答案 0 :(得分:1)
在您的示例中,我们要做的是导出mapStateToProps
和mapDispatchToProps
,并为它们编写单元测试(当它们不重要时)。
我想您已经对动作创建者,saga和reduce进行了单元测试。
到目前为止,集成还剩下什么?您可能希望将组件安装在实际存储的上下文中,以查看它们是否对redux存储的突变做出正确的反应,以及它们是否调度正确的操作。在我的项目中,我们使用端到端浏览器自动化测试来验证这样的事情。
答案 1 :(得分:0)
如果要编写集成测试,请考虑为您的应用编写UI测试,以进行完整的端到端测试。网络选项很多:
或React Native:
对于单元测试,您应该能够逐个文件地执行此操作,而不必导出整个组件。请参阅redux saga单元测试示例:https://github.com/redux-saga/redux-saga/blob/master/docs/advanced/Testing.md
答案 2 :(得分:0)
好的,这是测试使用Redux的组件的一种方法。用故事书来演示。
首先,在配置商店时,您需要接受初始状态:
import { createStore, applyMiddleware } from 'redux';
import rootReducer from './combineReducers';
import thunk from 'redux-thunk'; // In your case use saga
const ConfigureStore = (initialState) => {
let middleware = applyMiddleware(thunk);
const store = initialState ?
createStore(rootReducer, initialState, middleware)
: createStore(rootReducer, middleware);
return store;
};
export default ConfigureStore;
这样,您可以注入初始状态以测试某些特定情况。
现在,为了测试用户交互,您需要分派用户可以执行的操作,然后验证组件的状态。
请参见以下示例:
import React from 'react';
import configureStore from '../_setup';
import { storiesOf } from '@storybook/react';
import { Provider } from 'react-redux';
import { specs, describe, it } from 'storybook-addon-specifications'
import { configure, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { expect } from 'chai';
import Greeting from '../components/Greeting';
let store = configureStore();// Here initializing the store, you can pass the initial state also.
configure({ adapter: new Adapter() });
storiesOf('Greetings with Redux', module)
.add('User says hello', () => {
// here you pass the store to the component
const storyWithProvider = (
<Provider store={store}>
<Greeting />
</Provider>
);
// Here you execute the action you want to test.
store.dispatch({
type: 'SayHelloAction',
payload: 'Jhon Doe'
});
specs(() => describe('User says hello', function () {
it('Should have greeting message with the user name', function () {
const output = mount(storyWithProvider);
// Here you verify the state of the component
expect(output.text()).to.contains('Hello: Jhon Doe');
});
}));
return storyWithProvider;
});
您还可以执行一些操作,以获得所需的结果。
例如
store.dispatch({
type: constants.actions.SHOW_VENDOR_PRODUCTS,
payload: selectedVendor
});
store.dispatch({
type: constants.actions.VENDOR_ACCEPTS_ORDER,
payload: false
});
store.dispatch({
type: constants.actions.ADD_PRODUCT,
payload: selectedProduct
});
然后验证结果:
expect(wrapper.find('.btn .btn-lg .btn-success')).to.have.length.of(1);
有关参考,请参见此example project,请参见“规格”标签以验证测试:
在这里,我正在使用故事书进行演示,但是您也可以使用简单的摩卡咖啡来做同样的事情。
希望有帮助。