Какой лучший способ для насмешки реагировать хуки для TDD (шутка)? - PullRequest
0 голосов
/ 17 марта 2020

Привет, я не уверен, что лучший способ издеваться над реагирующим крючком. Я хочу проверить страницу. js, которая имеет входы и отправить данные входов на сервер через запрос POST. Когда запрос выполнен успешно, появляется другая форма.

Я хочу проверить успешное выполнение.

Я использую пользовательский хук, вызывающий api, и его имя - useApi. Итак, я высмеял useApi, чтобы вернуть статус успеха. У меня есть 2 хука useAPI, и хуки вызываются при каждом рендеринге.

, поскольку setState of useState вызывает рендеринг, когда он вызывается, каждый useApi вызывается снова. поэтому должно быть много useApi.mockReturnValueOnce ().

было бы так много useApi.mockReturnValueOnce (), если есть больше useApi. это было бы очень неприятно, поэтому я выясняю, есть ли лучший метод.

У вас есть идеи?

// Page.js
const Page = () => {
  const [api, requestApi] = useApi(
    '/v1/users/me/marketing_agreement',
    {
      method: 'post',
      manual: true,
    }
  )
  const [verifyApi, requestVerifyApi] = useApi(
    '/v1/users/me/verify_password',
    {
      method: 'post',
      manual: true,
    }
  )
  ...
  return (
    <div>
      {api.status === 'success' ? <p>success</p> : null}
      <form
        onSubmit={e => {
          requestApi();
        }}
      >
        <input name="a" /> 
        ...
      </form>
    </div>
  )
}

// Page.test. js

test('test', async () => {
  // api
  useApi.mockReturnValueOnce([{ status: 'init' }, requestApi]);
  // verifyApi
  useApi.mockReturnValueOnce([{ status: 'init' }, requestApi]);

  // api
  useApi.mockReturnValueOnce([{ status: 'success' }, requestApi]);
  // verifyApi
  useApi.mockReturnValueOnce([{ status: 'init' }, requestApi]);

  // api
  useApi.mockReturnValueOnce([{ status: 'success' }, requestApi]);
  // verifyApi
  useApi.mockReturnValueOnce([{ status: 'init' }, requestApi]);

  ...some tests changing state of Page (and the page call useApi again because of rerendering)
})

// useApi. js

import { useReducer, useEffect } from 'react';
import request from 'libs/request';

const initialState = { status: 'init', data: null, error: null };
function reducer(_, action) {
  switch (action.type) {
    case 'request':
      return { status: 'loading' };
    case 'success':
      return { status: 'success', data: action.data };
    case 'failure':
      return { status: 'failure', error: action.error };
    default:
      throw new Error();
  }
}

export default (url, options = { method: 'get', manual: false }) => {
  const [state, dispatch] = useReducer(reducer, initialState);
  useEffect(() => {
    let cancelled = false;
    if (!options.manual) {
      dispatch({ type: 'request' });
      const { manual, ...others } = options;
      request({ url, ...others })
        .then(result => {
          if (!cancelled) {
            dispatch({ type: 'success', data: result.data });
          }
        })
        .catch(e => {
          if (!cancelled) {
            dispatch({ type: 'success', error: e });
          }
        });
    }
    return () => {
      cancelled = true;
    };
  }, [options, url]);
  if (options.manual) {
    const requestApi = async props => {
      dispatch({ type: 'request' });
      try {
        const { manual, ...others } = options;

        const result = await request({
          url,
          method: options.method,
          ...others,
          ...props,
        });
        dispatch({ type: 'success', data: result.data });
        return result;
      } catch (e) {
        dispatch({ type: 'failure', error: e });
        return null;
      }
    };
    return [state, requestApi];
  }
  return [state];
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...