библиотека реактивного тестирования-экземпляра ios .create ({}) - PullRequest
1 голос
/ 10 февраля 2020

Я хочу протестировать свой API с помощью response-testing-library И я экспортирую экземпляр, созданный с помощью ax ios .create, из файла с именем apiClient.ts

import axios from 'axios'

const apiClient = axios.create({
  baseURL: process.env.REACT_APP_API_URL,
  responseType: 'json',
  headers: {
    'Content-Type': 'application/json',
  },
})

export default apiClient

Затем используйте экземпляры топора ios, полученные от apiClient, в моих users.ts fetchUsersApi

import apiClient from './apiClient'

export interface ITrader {
  id: number
  name: string
  username: string
  email: string
  address: any
  phone: string
  website: string
  company: any
}

export const fetchTradersApi = async (): Promise<ITrader[]> => {
  const response = await apiClient.get<ITrader[]>('/users')
  return response.data
}

Я создал папку mocks и добавил в нее топор ios .ts

export default {
  get: jest.fn(() => Promise.resolve({ data: {} })),
}

Мои пользователи.spe c .tsx выглядит так:

import { cleanup } from '@testing-library/react'
import axiosMock from 'axios'
import { fetchTradersApi } from './traders'

jest.mock('axios')

describe.only('fetchTradersApi', () => {
  
  afterEach(cleanup)
  it('Calls axios and returns traders', async () => {
    axiosMock.get.mockImplementationOnce(() =>
      Promise.resolve({
        data: ['Jo Smith'],
      })
    )
    const traders = await fetchTradersApi()
    expect(traders).toBe([{ name: 'Jo Smith' }])
    expect(axiosMock.get).toHaveBeenCalledTimes(1)
    expect(axiosMock.get).toHaveBeenCalledWith(`${process.env.REACT_APP_API_URL}/users`)
  })
})

Я запускаю свой тест и получаю: Набор тестов не удалось запустить

TypeError: _axios.default.create is not a function

  1 | import axios from 'axios'
  2 |
> 3 | const apiClient = axios.create({

Пожалуйста, помогите мне решить проблему, создав правильный топор ios макет, работающий с библиотекой реагирующего тестирования, Tnx заранее.

1 Ответ

0 голосов
/ 03 апреля 2020

Потратив целый день, я нашел решение той же проблемы, что и у меня. Проблема, с которой я столкнулся, связана с комбо JEST, Node и Typescript. Позвольте мне кратко рассказать о файлах, которые играют роль в этом:

  1. ax ios -instance.ts // инициализация ax ios
  2. api.ts // контроллер api
  3. api.spe c .ts // api test files

ax ios -instance.ts

import axios, { AxiosInstance } from "axios";

const axiosInstance: AxiosInstance = axios.create({
    baseURL: `https://example-path/products/`,
    headers: {
        'Content-Type': 'application/json'
    }
});

export default axiosInstance;

api.ts

"use strict";

import {Request, Response, RequestHandler, NextFunction} from "express";
import axiosInstance from "./axios-instance";

/**
 * POST /:productId
 * Save product by productId
 */
export const save: RequestHandler = async (req: Request, res: Response, next: NextFunction) => {
    try {
        const response = await axiosInstance.post(`${req.params.id}/save`, req.body);
        res.status(response.status).json(response.data);
    } catch (error) {
        res.status(error.response.status).json(error.response.data);
    }
};

api.spe c .ts

import { save } from "./api";
import axiosInstance from "./axios-instance";

describe.only("controller", () => {

    describe("test save", () => {

        let mockPost: jest.SpyInstance;

        beforeEach(() => {
            mockPost = jest.spyOn(axiosInstance, 'post');
        });

        afterEach(() => {
            jest.clearAllMocks();
        });

        it("should save data if resolved [200]", async () => {

            const req: any = {
                params: {
                    id: 5006
                },
                body: {
                    "productName": "ABC",
                    "productType": "Food",
                    "productPrice": "1000"
                }
            };
            const res: any = {
                status: () => {
                    return {
                        json: jest.fn()
                    }
                },
            };
            const result = {
                status: 200,
                data: {
                    "message": "Product saved"
                }
            };

            mockPost.mockImplementation(() => Promise.resolve(result));

            await save(req, res, jest.fn);

            expect(mockPost).toHaveBeenCalled();
            expect(mockPost.mock.calls.length).toEqual(1);
            const mockResult = await mockPost.mock.results[0].value;
            expect(mockResult).toStrictEqual(result);
        });

        it("should not save data if rejected [500]", async () => {

            const req: any = {
                params: {
                    id: 5006
                },
                body: {}
            };
            const res: any = {
                status: () => {
                    return {
                        json: jest.fn()
                    }
                },
            };
            const result = {
                response: {
                    status: 500,
                    data: {
                        "message": "Product is not supplied"
                    }
                }
            };

            mockPost.mockImplementation(() => Promise.reject(result));

            await save(req, res, jest.fn);

            expect(mockPost).toHaveBeenCalled();
            const calls = mockPost.mock.calls.length;
            expect(calls).toEqual(1);
        });
    });
});

Для опубликованного требования мы должны высмеять «axiosInstance» не фактический объект «ax ios» из библиотеки, поскольку мы выполняем наш вызов из axiosInstance.

В файле spe c мы импортировали axiosInstance, а не фактический топор ios

import axiosInstance from "./axios-instance";

Затем мы создали шпиона для метода post (get / post / put все, что вы можете шпионить)

let mockPost: jest.SpyInstance;

Инициализация перед каждым, чтобы каждый тестовый случай имел шпиона fre sh для начала, а также очистка макетов необходима после каждого.

beforeEach(() => {
    mockPost = jest.spyOn(axiosInstance, 'post');
});

afterEach(() => {
    jest.clearAllMocks();
});

Насмешка над реализацией решена / отклонена

mockPost.mockImplementation(() => Promise.resolve(result));
mockPost.mockImplementation(() => Promise.reject(result));

Затем вызывается фактический метод

await save(req, res, jest.fn);

Проверка ожидаемых результатов

expect(mockPost).toHaveBeenCalled();
expect(mockPost.mock.calls.length).toEqual(1);
const mockResult = await mockPost.mock.results[0].value;
expect(mockResult).toStrictEqual(result);

Надеюсь, это поможет и Вы можете связать решение с вашей проблемой. Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...