首页 > 解决方案 > 如何开玩笑地测试 redux 表单

问题描述

我正在使用其中包含 reduxform 的无状态组件。我正在尝试为登录表单编写单元测试以获取输入详细信息以及模拟单击时的表单。但我不知道从哪里开始,因为我是开玩笑的新手。

我试图创建快照以及创建模拟商店。

登录表单组件:

import logo from 'assets/img/logo/logo_200.png';
import LoadingButton from 'components/LoadingButton';
import ReduxFormInput from 'components/ReduxFormInput';
import { password } from 'lib/normalize';
import React from 'react';
import { Form } from 'reactstrap';
import { Field, reduxForm } from 'redux-form';
import validate from './validate';

const SignInForm = (props: any) => {
  const { handleSubmit, isLoading } = props;
  return (
    <Form onSubmit={handleSubmit}>
      <div className="text-center pb-4">
        <img src={logo} className="rounded" style={{ width: 60, height: 60 }} alt="logo" />
      </div>
      <Field
        name="email"
        component={ReduxFormInput}
        placeHolder="your@email.com"
        label="Email"
        type="email"
      />
      <Field
        name="password"
        component={ReduxFormInput}
        placeHolder="your password"
        label="Password"
        type="password"
        normalize={password}
      />
      <hr />
      <LoadingButton
        text="Login"
        loadingText="Logging in"
        isLoading={isLoading}
        size="lg"
        block={true}
      />
    </Form>
  );
};

export default reduxForm({
  form: 'signIn',
  validate,
})(SignInForm);

Redux 表单输入组件:

import React from 'react';
import { FormGroup, Input, Label } from 'reactstrap';
import 'styles/splash-scripts.css';

const ReduxFormInput: React.FC = (field: any) => (
  <FormGroup>
    <Label>{field.label}</Label>
    <Input {...field.input} type={field.type} placeholder={field.placeHolder} />
    {field.meta.touched && <p className="text-danger">{field.meta.error}</p>}
  </FormGroup>
);

export default ReduxFormInput;

测试文件:

import React from 'react';
import { shallow, mount, render } from 'enzyme';
import { Provider } from "react-redux";
import renderer from 'react-test-renderer';
import configureMockStore from "redux-mock-store";

import SignInForm from '../../src/pages/Public/SignIn/SignInForm';

const mockStore = configureMockStore();
const store = mockStore({});


const defaultProps = {
  submitting: false,
  handleSubmit: () => {},
  invalid: false,
  initialValues: {},
};
describe("Login Component", () => {

  it('should match the snapshot', () => {
      const wrapper = renderer.create(
        <Provider store={store}>
            <SignInForm />
        </Provider>
    ).toJSON();
      expect(wrapper).toMatchSnapshot();
  });

  it('it renders a <form /> element', () => {
    const wrapper = shallow(
      <Provider store={store}>
         <SignInForm {...defaultProps} />
      </Provider>
    ).dive();
  });
});

我试过用

    const emailState = wrapper.state().email;
    const passwordState = wrapper.state().password;
    expect(emailState).toEqual('');
    expect(passwordState).toEqual('');

但我有一个错误

error: reactwrapper::state() can only be called on class components

标签: reactjsreduxjestjsredux-form

解决方案


正如错误所说,您不能调用state(). reactWrapper从您的评论来看,您似乎正在尝试检查空电子邮件和密码字段的类型和内容。如果是这种情况,您可以find这样命名:

const emailField = wrapper.find('[name="email"]')
const passwordField = wrapper.find('[name="password"')

然后,您可以根据需要检查值和类型。


推荐阅读