Jest + Enzyme:测试Redux-form

时间:2018-04-05 06:18:21

标签: react-redux jestjs jsx redux-form enzyme

我的应用程序有很多redux-form。我正在使用Jest和Enzyme进行单元测试。但是,我没有测试redux-form。我的组件是一个登录表单,如:

import { login } from './actions';
export class LoginForm extends React.Component<any, any> {

  onSubmit(values) {
    this.props.login(values, this.props.redirectUrl);
  }

  render() {
    const { handleSubmit, status, invalid } = this.props;

    return (
      <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
        <TextField label="Email" name="email">
        <TextField type="password" label="Password" name="password" autoComplete/>
        <Button submit disabled={invalid} loading={status.loading}>
          OK
        </Button>
      </form>
    );
  }
}

const mapStateToProps = (state) => ({
  status: state.login.status,
});

const mapDispatchToProps = { login };

const form = reduxForm({ form: 'login' })(LoginForm);

export default connect(mapStateToProps, mapDispatchToProps)(form);

模拟商店,导入连接组件

redux-form使用商店来维护表单输入。然后我使用redux-mock-store

import ConnectedLoginForm from './LoginForm';

const configureStore = require('redux-mock-store');
const store = mockStore({});
const spy = jest.fn(); 

const wrapper = shallow(
  <Provider store={store}>
    <ConnectedLoginForm login={spy}/>
  </Provider>);

wrapper.simulate('submit');
expect(spy).toBeCalledWith();

但是这样,submit没有被模拟,我的测试用例失败了:

  

调用的预期模拟函数:[]   但它没有被召集。

模拟商店,仅导入React组件。

我尝试从测试代码创建redux表单:

import { Provider } from 'react-redux';
import ConnectedLoginForm, { LoginForm } from './LoginForm';

const props = {
  status: new Status(),
  login: spy,
};
const ConnectedForm = reduxForm({
  form: 'login',
  initialValues: {
    email: 'test@test.com',
    password: '000000',
  },
})(LoginForm);

const wrapper = shallow(
  <Provider store={store}>
    <ConnectedForm {...props}/>
  </Provider>);

console.log(wrapper.html());

wrapper.simulate('submit');
expect(spy).toBeCalledWith({
  email: 'test@test.com',
  password: '000000',
});

在这种情况下,我仍然遇到function not called的错误。如果我添加console.log(wrapper.html()),我收到错误:

  

不变违规:无法在上下文中找到“存储”或   “连接(ConnectedField)”的道具。将根组件包装在中   a,或明确地将“store”作为道具传递给   “连接(ConnectedField)”。

我无法在官方网站上找到redux-form或redux或jest / enzyme,甚至谷歌的文件..请帮助,谢谢。

4 个答案:

答案 0 :(得分:0)

我遇到了类似的问题。答案可以在https://github.com/airbnb/enzyme/issues/1002找到。 简而言之,您应该将商店作为道具传递到您的表单中,并在包装​​器上使用.dive()函数。

此致

的Pavel

答案 1 :(得分:0)

您可以在此处找到答案:https://github.com/tylercollier/redux-form-test

简而言之,您可以使用浅潜()函数测试高阶组件,但在您的情况下,您可以在高阶组件中包含一个高阶组件。

您需要将组件分为两个组件,第一个是演示组件,不带

const form = reduxForm({ form: 'login' })(LoginForm);
export default connect(mapStateToProps, mapDispatchToProps)(form); 

然后将第一个组件包装到第二个组件(容器组件)中。

您可以轻松测试第一个组件(演示组件)

答案 2 :(得分:0)

我制作了一个工具来解决此类问题。它使用真实数据(chrome扩展程序将其收集并保存到文件)制作了一个测试用例,您可以使用CLI工具运行该测试用例。 我建议您尝试一下:https://github.com/wasteCleaner/check-state-management

答案 3 :(得分:0)

我使用了真正的商店(因为redux-mock-store不支持reducer)和redux-form的reducer对我有用。代码示例:


import { createStore, Store, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { reducer as formReducer } from 'redux-form';

const rootReducer = combineReducers({
  form: formReducer,
});

let store;

describe('Redux Form', () => {

  beforeEach(() => {
    store = createStore(rootReducer);
  });

  it('should submit form with form data', () => {
    const initialValues = {...};
    const onSubmit = jest.fn();
    const wrapper = mount(
      <Provider store={store}>
        <SomeForm
          onSubmit={onSubmit}
          initialValues={initialValues}
        />
      </Provider>
    );

    const form = wrapper.find(`form`);
    form.simulate('submit');

    const expectedFormValue = {...};
    expect(onSubmit).toHaveBeenCalledTimes(1);
    expect(onSubmit.mock.calls[0][0]).toEqual(expectedFormValue);
  });

});