Библиотека тестирования React с редактором, издевающимся над Axios в действии

#javascript #reactjs #react-redux #jestjs #react-testing-library

Вопрос:

У меня есть приложение, в которое я добавляю интеграционные тесты для изучения библиотеки тестирования React. Он встроен в стек MERN вместе с Redux для управления состоянием.

Моя тестовая оболочка-это стандартная настройка:

 import React from 'react';
import { render as rtlRender } from '@testing-library/react';
import { createStore, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';

const render = (
  ui,
  {
    initialState,
    store = createStore(rootReducer, compose(applyMiddleware(thunk))),
    ...renderOptions
  } = {}
) => {
  const Wrapper = ({ children }) => {
    return <Provider store={store}>{children}</Provider>;
  };
  return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
};

export * from '@testing-library/react';

export { render };
 

В данный момент я пытаюсь протестировать форму входа в систему и ошибки, которые возвращаются, когда поля недействительны.

 import React from 'react';
import { Router } from 'react-router';
import '@testing-library/jest-dom';
import { createMemoryHistory } from 'history';
import { render, screen, fireEvent, waitFor } from '../../../utils/test-utils';
import Login from '../login';

jest.mock('axios', () => {
  return {
    post: jest.fn()
  };
});

describe('<Login/>', () => {
  beforeEach(() => {
    // Some requirements for the component to render in the test
    const history = createMemoryHistory();
    const state = '';
    history.push('/', state);

    render(
      <Router history={history}>
        <Login history={history} />
      </Router>
    );
  });
  test('should show empty email error', async () => {
    fireEvent.input(screen.getByRole('textbox', { name: /email/i }), {
      target: {
        value: ''
      }
    });

    fireEvent.submit(screen.getByRole('button', { name: /login/i }));

    await waitFor(() => {
      expect(screen.getByText(/email field is required/i)).toBeInTheDocument();
    });
  });
});
 

К сожалению, когда я запускаю этот тест, он дает мне TypeError: Cannot read property 'then' of undefined , и я не могу понять, почему

My action looks like:

 export const loginUser = (userData) => (dispatch) => {
  return axios
    .post('/api/users/login', userData)
    .then((res) => {
      const { token } = res.data;
      localStorage.setItem('jwtToken', token);
      setAuthToken(token);
      const decoded = jwt_decode(token);
      dispatch(setCurrentUser(decoded));
    })
    .catch((err) =>
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      })
    );
};
 

Вместо того, чтобы тестировать действия/редукторы в моей кодовой базе, я бы предпочел проверить, что должен видеть пользователь, и это то, что я прочитал, поощряет библиотека тестирования.

Я также использую крючки redux — useDispatch/useSelector во всем моем приложении.

Любая помощь будет признательна 🙂