为什么我在这里不能使用模拟嘲笑值?

时间:2020-09-20 17:18:30

标签: javascript reactjs axios jestjs react-testing-library

我不清楚在使用以下设置时如何模拟我的api响应。

我进行了以下测试:

import React from 'react';
import { cleanup, render, wait } from '@testing-library/react';
import axios from 'axios';
import Condition from './index.jsx';

jest.mock('axios', () => {
  return {
    create: jest.fn(() => ({
      get: jest.fn().mockResolvedValue({ data: {} }),
      interceptors: {
        request: { use: jest.fn(), eject: jest.fn() },
        response: { use: jest.fn(), eject: jest.fn() },
      },
    })),
  };
});


afterEach(cleanup);

test('fetches and displays data', async () => {
  axios.get.mockResolvedValue({ data: 'mock data' });
  const { container } = render(<Condition {...props} />);
  await wait(() => expect(container.textContent).toContain('Current milestone'));
  expect(container).toBeDefined();
});

…和以下api帮助器:

import axios from 'axios';

const api = axios.create({
  baseURL: window.apiPath,
  withCredentials: true,
});

api.interceptors.request.use(config => {
  const newConfig = Object.assign({}, config);
  newConfig.headers.Accept = 'application/json';

  return newConfig;
}, error => Promise.reject(error));

export default api;

我的Condition组件在安装时使用以下函数来获取数据:

const fetchAsync = async endpoint => {
  const result = await api.get(endpoint);
  setSuffixOptions(result.data.data);
  console.log('result.data.data', result.data.data);
};

测试中的axios.get.mockResolvedValue({ data: 'mock data' });行会导致以下错误:

    TypeError: Cannot read property 'mockResolvedValue' of undefined

      124 |
      125 | test('fetches and displays data', async () => {
    > 126 |   axios.get.mockResolvedValue({ data: 'mock data' });
          |             ^
      127 |   const { container } = render(<Condition {...props} />);
      128 |   await wait(() => expect(container.textContent).toContain('Current milestone'));
      129 |   expect(container).toBeDefined();

我应该使用其他方法来模拟响应吗?

编辑 调用axios.create.get.mockResolvedValue({ data: 'mock data' });会导致相同的错误。

2 个答案:

答案 0 :(得分:2)

要模拟您的api响应,可以将jest.spyOnmockImplementation结合使用,例如如下:

import api from './api';

const mock = jest.spyOn(api,"get");
mock.mockImplementation(() => Promise.resolve({ data: {} }));

在上面的示例中,api.get方法被替换为模拟成功返回{ data: 'mock data' }的调用。

可以将其放置在test函数中,如下所示:

test('fetches and displays data', async () => {
    const mock = jest.spyOn(api, "get");
    mock.mockImplementation(() => Promise.resolve({ data: {} }));
    const { container } = render(<Condition {...props} />);
    await wait(() => expect(container.textContent).toContain('Current milestone'));
    expect(container).toBeDefined();
});

答案 1 :(得分:1)

更好的方法是模拟./api帮助程序模块,而不是axios模块。因为您正在测试导入./api作为其直接依赖项的组件。对于组件,axios模块是间接依赖项。如果要测试./api助手,则应该模拟axios模块,因为现在,它成为./api的直接依赖项。

例如

index.tsx

import React, { useEffect, useState } from 'react';
import api from './api';

function Condition(props) {
  const [options, setSuffixOptions] = useState();
  const fetchAsync = async (endpoint) => {
    const result = await api.get(endpoint);
    setSuffixOptions(result.data);
    console.log('result.data', result.data);
  };
  useEffect(() => {
    fetchAsync('http://localhost:3000/api');
  });

  return <div>{options}</div>;
}

export default Condition;

index.test.tsx

import React from 'react';
import Condition from './';
import { render, wait } from '@testing-library/react';
import api from './api';
import { mocked } from 'ts-jest/utils';

jest.mock('./api', () => {
  return { get: jest.fn() };
});

describe('63981693', () => {
  test('fetches and displays data', async () => {
    mocked(api.get).mockResolvedValue({ data: 'mock data' });
    const props = {};
    const { container } = render(<Condition {...props} />);
    await wait(() => expect(container.textContent).toContain('mock data'));
    expect(api.get).toBeCalledWith('http://localhost:3000/api');
    expect(container).toBeDefined();
  });
});

我们不关心./api模块的实现,因为我们已经对其进行了模拟。

具有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/63981693/index.test.tsx (12.377s)
  63981693
    ✓ fetches and displays data (68ms)

  console.log src/stackoverflow/63981693/index.tsx:1461
    result.data mock data

  console.log src/stackoverflow/63981693/index.tsx:1461
    result.data mock data

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |      100 |      100 |      100 |      100 |                   |
 index.tsx |      100 |      100 |      100 |      100 |                   |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        14.873s, estimated 18s
相关问题