Typescript Jest说mock或mockReturnedValue不存在于我想mock的类型上

xzabzqsa  于 2023-04-03  发布在  Jest
关注(0)|答案(6)|浏览(168)

下面是我想测试的一个类:

//Request.js
import axios, {AxiosInstance} from 'axios';
import config from './config';

const axiosSingleton: AxiosInstance = axios.create({
  baseURL: 'http://localhost:8080',
});

export default class Request {
  public async get<$ResponseType = any>(url: string): Promise<void> {
    const response = await axiosSingleton.get(url);
    return response.data;
  }
}

当我通过创建一个测试文件来测试它时,我不知道如何模拟axios。我尝试了很多方法,包括- spyOn和自动模拟。但它们似乎不起作用。下面是一个版本的测试文件,我不明白为什么它不起作用

// Request.test.js
import axios from 'axios';
import Request from './Request';

interface ITestResponseDataType {
  value: string
}

jest.mock('axios');

describe('Request Tests', () => {
  it('should call axios get with the right relativeUrl', async () => {
    const getMock = jest.fn();

    axios.create.mockReturnValue({
      get: getMock
    });

    getMock.mockResolvedValue({
      value: 'value'
    });

    const data = await new Request().get<ITestResponseDataType>('/testUrl');
    expect(getMock.mock.calls.length).toEqual(1);
    expect(data).toEqual({
      value: 'value'
    });
  });
});

当我尝试运行测试时得到的错误是-

TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
    src/common/api/Request.test.ts:15:18 - error TS2339: Property 'mockReturnValue' does not exist on type '(config?: AxiosRequestConfig | undefined) => AxiosInstance'.

    15     axios.create.mockReturnValue({

这个错误是有道理的,因为axios中为axios.create定义的类型不应该允许在. create上调用.mockReturnValue。那么我如何告诉typescript jest已经进入并修改了它?

wj8zmpe1

wj8zmpe11#

将mock方法强制转换为jest.Mock,即

import axios from "axios"
import Request from "./Request";

// Create an Axios mock
// Don't worry about the order, Jest will hoist this above the imports
// See https://jestjs.io/docs/manual-mocks#using-with-es-module-imports
jest.mock("axios", () => ({
  create: jest.fn()
}))

// Customise the `create` mock method
(axios.create as jest.Mock).mockReturnValue({
  get: getMock
})
h9vpoimq

h9vpoimq2#

只是一个最高评价答案的补充。我更喜欢在类型转换时维护类型定义。这可以重写为

(axios as jest.Mocked<typeof axios>).create.mockReturnValue({
  get: getMock
});
fcy6dtqo

fcy6dtqo3#

你需要用一个Jest模拟函数替换axios.create方法:

axios.create = jest.fn();

这将允许您设置其返回值。

h9a6wy2h

h9a6wy2h4#

我用axios-mock-adapter解决了这个问题,它对我来说没有任何问题,而且还有助于嵌套调用。

// src/request.ts
    import axios from "axios";
    export const axiosCreate = axios.create();
    export async function someRequest(){
      axiosCreate.get("http://localhost/users");
    }

    // src/__test__/request.test.ts
    import * as request from ".../request";
    import MockAdapter from "axios-mock-adapter";
    const mock = new MockAdapter(request.axiosCreate);
    it("Testing mock", async () => {
      mock.onGet("http://locahost/users").reply(200, "ok");
      const resp = await request.someRequest();
      expect(resp).toEqual("ok");
    });

希望能帮助到别人。

ulmd4ohb

ulmd4ohb5#

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

beforeEach(() => {
jest.resetAllMocks();
mockedAxios.get.mockResolvedValue({
data: []
});
});

对我来说,只有这种方式是axios模拟功能

qni6mghb

qni6mghb6#

这个例子是一个不同的库,但类似的任务。在将导入转换为jest.Mocked<typeof MyImport>之后,我只需要将mock函数分配给它的属性,而不是使用mockReturnValue方法。至少这是一种可行的方法。

import Reactotron from '../../reactotron'
import { makeEnhancers } from './enhancers'

jest.mock('../../reactotron')
const mockReactotron = Reactotron as jest.Mocked<typeof Reactotron>

describe('makeEnhancers', () => {
  describe('given Reactotron createEnhancer exists', () => {
    beforeEach(() => {
      mockReactotron.createEnhancer = jest.fn()
    })
    it('appends the reactotron enhancer', () => {
      const enhancers = makeEnhancers()
      expect(enhancers).toHaveLength(1)
    })
  })

  describe('given Reactotron createEnhancer does not exist', () => {
    beforeEach(() => {
      mockReactotron.createEnhancer = undefined
    })
    it('does not append the reactotron enhancer', () => {
      const enhancers = makeEnhancers()
      expect(enhancers).toHaveLength(0)
    })
  })
})

相关问题