[英]integration tests for react redux redux-saga
I have a project structure like this: 我有这样的项目结构:
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
so I have no problem with unit test with this structure, but I'm pretty confused as to how to structure integration test. 所以我对使用这种结构的单元测试没有任何问题,但我对如何构建集成测试感到困惑。 For my unit tests I am exporting each scene component as a class
对于我的单元测试,我将每个场景组件导出为一个类
export class SomeComponent extends Component {}
and as a redux connected component 并作为redux连接组件
export default connect(
mapStateToProps,
mapDispatchToProps
)(SomeComponent)
So for the fist style of export (the class) I am unit testing it, but for the second way (the connected component way) I am unsure how to approach this specifically how to do integration testing in react/redux. 因此,对于第一种导出方式(类)我是单元测试它,但对于第二种方式(连接组件方式),我不确定如何具体如何在react / redux中进行集成测试。 I've searched the internet about this, but nothing that is close to this structure.
我在互联网上搜索了这个,但没有任何接近这个结构。
So: 所以:
also, if it's #1 then how should I test routes via react router? 另外,如果它是#1那么我应该如何通过反应路由器测试路由?
In the case of your example, what we do is export mapStateToProps
and mapDispatchToProps
and we write unit tests for those (when they are not trivial). 在你的例子中,我们做的是导出
mapStateToProps
和mapDispatchToProps
,我们为那些编写单元测试(当它们不是微不足道的时候)。
I suppose you already unit test your action creators, sagas and reducers on their own. 我想你已经自己单独测试了你的动作创造者,传奇和减速器。
What's left as far as integration goes? 整合到底还剩下什么? You might want to mount the components in the context of a real store, to see if they react correctly to mutations of the redux store and whether they dispatch the correct actions or not.
您可能希望在真实存储的上下文中安装组件,以查看它们是否对redux存储的突变做出了正确的反应,以及它们是否分派了正确的操作。 In my project, we use end-to-end browser automation tests to verify things like this.
在我的项目中,我们使用端到端浏览器自动化测试来验证这样的事情。
If you want to write integration tests, consider writing UI tests for your app that will do full end to end testing. 如果您想编写集成测试,请考虑为您的应用程序编写UI测试,以进行完整的端到端测试。 There are many web options:
有很多网页选项:
or React Native: 或反应原生:
As for unit testing, you should be able to do that on a file by file basis without having to export the whole component. 至于单元测试,您应该能够逐个文件地执行此操作,而无需导出整个组件。 See the redux saga unit testing example: https://github.com/redux-saga/redux-saga/blob/master/docs/advanced/Testing.md
请参阅redux saga单元测试示例: https : //github.com/redux-saga/redux-saga/blob/master/docs/advanced/Testing.md
Ok this is one way to test your components that use Redux. 好的,这是测试使用Redux的组件的一种方法。 Using storybook to demonstrate.
用故事书来演示。
First you need to accept the initial state when you are configuring the store: 首先,在配置存储时需要接受初始状态:
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;
This way you can inject your initial state to test some specific cases. 这样您就可以注入初始状态来测试某些特定情况。
Now in order to test the user interactions, you need to dispatch the actions the user can execute, and then verify the state of your components. 现在,为了测试用户交互,您需要调度用户可以执行的操作,然后验证组件的状态。
See this example: 看这个例子:
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;
});
Also you can execute several actions, to get the result you want. 您还可以执行多个操作,以获得所需的结果。
eg 例如
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
});
And then verify the result: 然后验证结果:
expect(wrapper.find('.btn .btn-lg .btn-success')).to.have.length.of(1);
For reference see this example project , see the Specifications tab to validate the tests: 有关参考,请参阅此示例项目 ,请参阅规范选项卡以验证测试:
Here I'm using storybook to demostrate, but you can also do the same with simple mocha. 在这里我使用故事书进行演示,但你也可以用简单的摩卡语做同样的事情。
Hope this help. 希望这有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.