Как тестировать / имитировать вызовы API с помощью JEST в приложении Create React - PullRequest
0 голосов
/ 29 мая 2020

Здравствуйте, я пытаюсь протестировать свои создатели асинхронных c действий в приложении create response, но у меня недостаточно информации, чтобы исправить проблему. Я впервые тестирую asyn c действия в react. Я использую ax ios для получения API и jest mock для создания фиктивных функций.

Вот функция выборки:

export async function signUpAPI(userSignupInfo: ILoginSignUpFormParams): Promise<ILoginSignupResponse> {
  const { username, email, password } = userSignupInfo;
  try {
    const res = await axiosInstance.post('/signup', {
      username,
      email,
      password
    });
    return res.data;
  } catch (error) {
    throw error.response.data;
  }
}

вот мой тест:

import * as sessionActions from '../Actions';
import { sessionInitialState } from 'models/Session/sessionInitialState';
import { SessionActionTypes } from '../Types';
import axios from 'axios';
import { signUpAPI } from 'api/sessions';

jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;

describe('Session Action Test', () => {
  describe('async ACTION Test', () => {
    describe('On signup', () => {
      it('should success response on signup', async () => {
        mockedAxios.post.mockResolvedValue({ data: {} });

        const t = await signUpAPI({ username: 'yousir1', password: 'Password1!', email: 'yousir1@gmail.com' });
        console.log(t);
      });
    });
  });
});

Вот ошибка, которую я получаю, но не понимаю, потому что я высмеиваю ее как Resolved value, но она попадает в мой блок catch в моем фактическом вызове API. Странно.

enter image description here

1 Ответ

0 голосов
/ 31 мая 2020

Мне потребовалось некоторое время, чтобы получить это, но я, наконец, понял это.

Итак, у меня есть такая структура папок:

src
├── api
│   └── sessions.ts
├── assets
├── components
├── helper
│   └── sessionSetup.ts
├── index.css
├── index.tsx
├── interfaces
├── lib
│   ├── __mocks__   <<-- you have to create a mock like this first----------
│   │   └── api.ts
│   ├── axios.instance.ts
│   └── axios.interceptors.ts
├── models
├── react-app-env.d.ts
├── routes
├── serviceWorker.ts
├── setupTests.ts
└── store
    ├── root
    ├── session
    │   ├── Actions.ts
    │   ├── Reducers.ts
    │   ├── Selectors.ts
    │   ├── Types.ts
    │   └── test
    │       ├── session.action.test.ts
    │       └── session.reducer.test.ts
    └── user
        ├── Actions.ts
        ├── Reducers.ts
        ├── Selectors.ts
        ├── Types.ts
        └── test
            ├── user.action.test.ts
            └── user.reducer.test.ts

тогда внутри папки __mock__ у меня есть это. Это будет имитировать мой API регистрации "POST"

export default {
  post: jest.fn(() =>
    Promise.resolve({
      data: {}
    })
  )
};

, поскольку я использую экземпляр ax ios, например:

import axios from 'axios';

const axiosInstance = axios.create({
  baseURL: process.env.REACT_APP_BASE_API_URL
});

export default axiosInstance;

, а затем использую его в своей папке API, например:

import axiosInstance from '../lib/axios.instance';
import { ILoginSignupResponse, ILoginSignUpFormParams } from 'interfaces/session';

export async function signUpAPI(userSignupInfo: ILoginSignUpFormParams): Promise<ILoginSignupResponse> {
  const { username, email, password } = userSignupInfo;
  try {
    const res = await axiosInstance.post('/signup', {
      username,
      email,
      password
    });
    return res.data;
  } catch (error) {
    throw error.response.data;
  }
}

, тогда мне нужно настроить свой тест следующим образом:

import * as sessionActions from '../Actions';
import { sessionInitialState } from 'models/Session/sessionInitialState';
import { SessionActionTypes } from '../Types';
import axios from 'axios';
import { signUpAPI } from 'api/sessions';
import axiosInstance from 'lib/axios.instance';

jest.mock('../../../lib/axios.instance.ts');
const mockedAxios = axiosInstance as jest.Mocked<typeof axiosInstance>;

describe('Session Action Test', () => {
  describe('async ACTION Test', () => {
    describe('On signup', () => {
      it('should success response on signup', async () => {
        mockedAxios.post.mockImplementationOnce(() => Promise.resolve({ data: { foo: 'bar' } }));

        const t = await signUpAPI({ username: 'yousir1', password: 'Password1!', email: 'yousir1@gmail.com' });
        console.log(t);
      });
    });
  });
});

jest.mock() примет путь к вашей макетной папке. Затем я могу использовать свою переменную mockedAxios, чтобы получить все свойства в моем файле __mock__/api.ts и протестировать свой API, дав ему обещание. Возврат переменной t будет тем, что вы поместили в метод Promise.resolve.

...