调度(操作)不会立即更新单元测试中的 Redux 状态



我正在为我的应用程序编写基于react和redux的测试用例。

container = TestUtils.renderIntoDocument(
  <Provider store={createStore({"key": "old_val"})}>
    {() => <Component />}
  </Provider>
);

在用initialState渲染之后,我分派一个动作,看看状态是否改变。

Component.store.dispatch({ type: 'SET_VAL', value: 'some_val' });
然后打印状态
console.log(store.getState());

我期望状态是{"key": "some_val"}。然而,它仍然显示{"key": "old_val"}

应用程序工作正常,只是没有测试,所以我的action-creatorsreducers不会有任何问题。

我在这里做错了什么吗?顺便说一句,我使用thunk中间件进行异步动作调度。它会干扰这里吗?如果是,我如何等待,直到异步操作完成?

更新:

这里显示的redux测试非常简单,但它们似乎工作得很好。

store.dispatch(addTodo('Hello'));
expect(store.getState()).toEqual([{
  id: 1,
  text: 'Hello'
}]);

redux的一个巨大好处是,它允许您使用纯函数和纯组件实现几乎所有的应用程序。Redux和react-redux抽象了订阅UI状态变化的实现细节,允许你单独测试应用程序的所有代码。这样,你就不需要在每次测试代码时都呈现一个带有存储的提供者,这大大降低了复杂性。

假设在你的状态中有一个key属性和一个KeyDisplay组件。你可以用下面的reducer文件实现这个状态:

reducers.js

import { combineReducers } from 'redux';
export function key(state, { type, value }) {
  switch(type) {
    case 'SET_VAL': return value;
    default: return state;
  }
}
export default combineReducers({ key });

你可以为我们的组件设置一个文件:

KeyDisplay.js

import React from 'react';
import { connect } from 'react-redux';
export function KeyDisplay({ keyProp }) {
  return (
    <div>The key is {keyProp}</div>
  );
}
export default connect((state) => { keyProp: state.key })(KeyDisplay);

然后在reduce的单元测试中,你可以只导入key的reducer并完全独立于用户界面进行测试:

keyReducer.test.js

import test from 'tape';
import { key } from './reducers.js';
test('key reducer', (t) => {
  t.plan(1);
  const output = key('old', { type: 'SET_VAL', value: 'new' });
  t.equal(output, 'new', 'SET_VAL should override old value');
});

另外,由于connect将状态作为道具传递到组件中,你可以用一些代表你感兴趣的状态的测试道具来渲染un connect组件,同样不需要设置store和provider:

KeyDisplay.test.js

import test from 'tape';
import { renderIntoDocument } from 'react-addons-test-utils';
import { KeyDisplay } from './KeyDisplay.js';
test('KeyDisplay', (t) => {
  const component = renderIntoDocument(<KeyDisplay keyProp="test" />);
  // test component
});

最新更新