Тестовый вызов функции redux-saga - PullRequest
0 голосов
/ 03 марта 2020

Я пытаюсь проверить форму, созданную с ant design и redux-form. Я создал container и component.

Я использовал redux-saga в качестве промежуточного программного обеспечения.

Когда монтируется UserFormContainer, он отправляет действие, а redux-saga выполняет действие и выполняет api вызывает и возвращает данные.

Существует initialize функция redux-form, которая заполняет форму.

Проблема в том, что я хочу проверить, заполняется ли форма или нет. Но у меня возникают проблемы с имитацией выборки данных при вызове componentdidmount().

UserFormContainer. js

import React, { Component } from "react";
import { connect } from "react-redux";
import UserForm from "../component/UserForm";
import { reduxForm } from "redux-form";
import actions from "../redux/actions";

class UserFormContainer extends Component {
  state = {
    loading: false
  };

  componentDidMount() {
    this.setState({
      loading: true
    });
    this.fetchUser();
  }

  fetchUser = () => {
    const { dispatch, initialize } = this.props;

    new Promise((resolve, reject) => {
      dispatch({
        type: actions.FETCH_USER,
        resolve,
        reject
      });
    })
      .then(response => {
        const {
          person: PersonEntityForm,
          contact: EmailEntityForm,
          phone: PhoneEntityForm,
          address: AddressEntityForm
        } = response;

        const userData = {
          PersonEntityForm,
          EmailEntityForm,
          PhoneEntityForm,
          AddressEntityForm
        };

        initialize(userData);
        this.setState({ loading: false });
      })
      .catch(error => console.log({ error }));
  };

  render() {
    const { loading } = this.state;
    return <UserForm loading={loading} />;
  }
}

const UserFormRedux = reduxForm({
  form: "UserForm"
})(UserFormContainer);

export default connect(null, dispatch => ({ dispatch }))(UserFormRedux);

UserFormContainer.test. js

import React from "react";
import { render, cleanup } from "@testing-library/react";
import "@testing-library/jest-dom";
import { reducer as formReducer } from "redux-form";
import { createStore, combineReducers } from "redux";
import { Provider } from "react-redux";
import UserFormContainer from "./UserFormContainer";
import userReducer from "../redux/reducers";
import { FETCH_USER } from "../redux/saga";

afterEach(cleanup);

const renderWithRedux = (
  component,
  {
    initialState,
    store = createStore(
      combineReducers({ userReducer, form: formReducer }),
      initialState
    )
  } = {}
) => {
  return {
    ...render(<Provider store={store}>{component}</Provider>)
  };
};

it("should fill form value", async () => {
  const fakeUser = {
    person: { firstName: "Don", lastName: "Joe" },
    contact: { email: "don@mail.com" },
    phone: { phone: "123456789", contactPhoneType: "personal" },
    address: {
      street: "Haven Street",
      street2: null,
      city: "Wingtown",
      state: "Wood",
      postalCode: "44600"
    }
  };

  jest.mock("../redux/saga", () => ({ FETCH_USER: jest.fn() }));
  FETCH_USER.mockImplementation(() => Promise.resolve(fakeUser));

  renderWithRedux(<UserFormContainer />);

  expect(mock).toHaveBeenCalled();
});

UserForm. js

import React, { Component } from "react";
import { FormSection } from "redux-form";
import { Form, Spin } from "antd";
import PersonalInformationForm from "./PersonalInformationForm";
import ContactEmailForm from "./ContactEmailForm";
import ContactPhoneForm from "./ContactPhoneForm";
import ContactAddressForm from "./ContactAddressForm";

class UserForm extends Component {
  render() {
    const { loading } = this.props;

    return (
      <Spin data-testid="spinning" spinning={loading}>
        <Form data-testid="userForm" style={{ width: "300px", margin: "auto" }}>
          <FormSection name="PersonEntityForm">
            <PersonalInformationForm />
          </FormSection>

          <FormSection name="EmailEntityForm">
            <ContactEmailForm />
          </FormSection>

          <FormSection name="PhoneEntityForm">
            <ContactPhoneForm />
          </FormSection>

          <FormSection name="AddressEntityForm">
            <ContactAddressForm />
          </FormSection>
        </Form>
      </Spin>
    );
  }
}

export default UserForm;

1 Ответ

0 голосов
/ 05 марта 2020

Проблема в том, что я пытаюсь проверить вызов функции на FETCH_USER. Мой компонент использует store.dispatch для вызова функции FETCH_USER. Итак, я вместо тестирования вызова функции FETCH_USER я тестировал для store.dispatch.

UserFormContainer.test. js

import React from "react";
import { render, cleanup } from "@testing-library/react";
import "@testing-library/jest-dom";
import { reducer as formReducer } from "redux-form";
import { createStore, combineReducers } from "redux";
import { Provider } from "react-redux";
import UserFormContainer from "./UserFormContainer";
import userReducer from "../redux/reducers";
import actions from "../redux/actions";

afterEach(cleanup);

const initialState = {};

const fakeStore = createStore(
  combineReducers({ userReducer, form: formReducer }),
  initialState
);

const renderWithRedux = (
  component,
  { initialState, store = fakeStore } = {}
) => {
  return {
    ...render(<Provider store={store}>{component}</Provider>)
  };
};

it("should fill form value", async () => {
  const fakeUser = {
    person: { firstName: "Don", lastName: "Joe" },
    contact: { email: "don@mail.com" },
    phone: { phone: "123456789", contactPhoneType: "personal" },
    address: {
      street: "Haven Street",
      street2: null,
      city: "Wingtown",
      state: "Wood",
      postalCode: "44600"
    }
  };

  fakeStore.dispatch = jest.fn();

 renderWithRedux(<UserFormContainer />);

  expect(fakeStore.dispatch).toHaveBeenCalled();
  expect(fakeStore.dispatch).toHaveBeenLastCalledWith({
    type: actions.FETCH_USER,
    resolve: expect.any(Function),
    reject: expect.any(Function)
  });
});

Далее, как моя dispatch функция завернут в new Promise(). Я протестировал значение resolved с небольшим изменением кода выше.

const fakeUser = {
  person: { firstName: "Don", lastName: "Joe" },
  contact: { email: "don@mail.com" },
  phone: { phone: "123456789", contactPhoneType: "personal" },
  address: {
    street: "Haven Street",
    street2: null,
    city: "Wingtown",
    state: "Wood",
    postalCode: "44600"
  }
};

const fakePromise = new Promise((resolve, reject) => {
    fakeStore.dispatch = jest.fn(() => {
      try {
        resolve(fakeUser);
      } catch (error) {
        reject("error");
      }
    });
  });

  renderWithRedux(<UserFormContainer />);

  expect(fakeStore.dispatch).toHaveBeenCalled();
  expect(fakeStore.dispatch).toHaveBeenLastCalledWith({
    type: actions.FETCH_USER,
    resolve: expect.any(Function),
    reject: expect.any(Function)
  });

  expect(fakePromise).resolves.toBe(fakeUser);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...