【问题标题】:Jest - Create React App - Axios: test get mocked开玩笑 - 创建 React 应用程序 - Axios:测试被嘲笑
【发布时间】:2021-11-30 11:55:24
【问题描述】:

我有一个axiosInstance.js axios 实例:

import axios from "axios"
import { REACT_FE_ACCESS_TOKEN } from "../../constants/constant";

const axiosInstance = axios.create({
  baseURL: process.env.REACT_APP_BACKEND_URL,
  headers: {
    "content-type": "application/json"
  },
  responseType: "json"
});

axiosInstance.interceptors.request.use((config) => {

  const token = localStorage.getItem(REACT_FE_ACCESS_TOKEN);
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;

});

export { axiosInstance };

我在课堂上称它为:

import { axiosInstance as api } from "./axiosInstance";

export default class ApiCrud {

  constructor(baseUrl) {
    this.baseUrl = baseUrl;
  }

  fetchItems() {
    return api.get(`${this.getBaseUrl()}`).then(result => result.data);
  }

  getBaseUrl() {
    return this.baseUrl;
  }

}

我想做一个写测试(使用 Create React App 和 Jest)。

这是axiosInstance.test.js 文件,有效:

import { axiosInstance } from "../../../../utils/api/base/axiosInstance";
import { REACT_FE_ACCESS_TOKEN } from "../../../../utils/constants/constant";

const token = "a1.b2.c3";

beforeEach(() => {
  localStorage.clear();
});

describe('Test API Instance', () => {
  it ('Test request interceptor with token', () => {
    localStorage.setItem(REACT_FE_ACCESS_TOKEN, token);
    expect(localStorage.getItem(REACT_FE_ACCESS_TOKEN)).toBe(token);
    const result = axiosInstance.interceptors.request.handlers[0].fulfilled({ headers: {} });
    expect(result.headers).toHaveProperty("Authorization");
  });

  it ('Test request interceptor without token', () => {
    const result = axiosInstance.interceptors.request.handlers[0].fulfilled({ headers: {} });
    expect(result.headers).not.toHaveProperty("Authorization");
  });
});

这是apiCrud.test.js

import ApiCrud from "../../../../utils/api/base/ApiCrud";

const mockedGet = {
  email: "info@example.com",
}

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

describe('Test API crud', () => {


  it ('Test can get base url', () => {
    const apiCrud = new ApiCrud('/fake-url');
    expect(apiCrud.getBaseUrl()).toBe('/fake-url');
  });

  it ('Test can fetch items', () => {
    const apiCrud = new ApiCrud('/fake-url');
    return apiCrud.fetchItems().then(data => {
      expect(data).toBe(mockedGet);
    })
  });
});

但我明白了

 FAIL  src/__tests__/utils/api/base/apiCrud.test.js
  ● Test API crud › Test can fetch items

    TypeError: Cannot read property 'then' of undefined

       8 |
       9 |   fetchItems() {
    > 10 |     return api.get(`${this.getBaseUrl()}`).then(result => result.data);
         |            ^
      11 |   }
      12 |
      13 |   getBaseUrl() {

      at ApiCrud.fetchItems (src/utils/api/base/ApiCrud.js:10:12)
      at Object.<anonymous> (src/__tests__/utils/api/base/apiCrud.test.js:29:20)

所以,我认为我在模拟 axios 的 get 时出错了,但是......如何解决?

【问题讨论】:

    标签: javascript reactjs unit-testing axios


    【解决方案1】:

    您正在测试依赖于./axiosInstance 模块的ApiCrud 类。模拟直接依赖 ./axiosInstance 模块比模拟间接依赖更简单 依赖 - axios 模块。

    ApiCrud.js:

    import { axiosInstance as api } from './axiosInstance';
    
    export default class ApiCrud {
      constructor(baseUrl) {
        this.baseUrl = baseUrl;
      }
    
      fetchItems() {
        return api.get(`${this.getBaseUrl()}`).then((result) => result.data);
      }
    
      getBaseUrl() {
        return this.baseUrl;
      }
    }
    

    ApiCrud.test.js:

    import ApiCrud from './ApiCrud';
    import { axiosInstance } from './axiosInstance';
    
    const mockedGet = {
      email: 'info@example.com',
    };
    jest.mock('./axiosInstance');
    
    describe('Test API crud', () => {
      afterEach(() => {
        jest.clearAllMocks();
      });
      afterAll(() => {
        jest.resetAllMocks();
      });
      it('Test can get base url', () => {
        const apiCrud = new ApiCrud('/fake-url');
        expect(apiCrud.getBaseUrl()).toBe('/fake-url');
      });
    
      it('Test can fetch items', () => {
        axiosInstance.get.mockResolvedValueOnce({ data: mockedGet });
        const apiCrud = new ApiCrud('/fake-url');
        return apiCrud.fetchItems().then((data) => {
          expect(data).toBe(mockedGet);
        });
      });
    });
    

    测试结果:

     PASS  examples/69531160/ApiCrud.test.js (10.676 s)
      Test API crud
        ✓ Test can get base url (3 ms)
        ✓ Test can fetch items (1 ms)
    
    ------------------|---------|----------|---------|---------|-------------------
    File              | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    ------------------|---------|----------|---------|---------|-------------------
    All files         |   73.33 |        0 |      80 |   71.43 |                   
     ApiCrud.js       |     100 |      100 |     100 |     100 |                   
     axiosInstance.js |   55.56 |        0 |       0 |   55.56 | 13-17             
    ------------------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       2 passed, 2 total
    Snapshots:   0 total
    Time:        14.978 s
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      • 1970-01-01
      • 2020-08-16
      • 1970-01-01
      • 2020-06-21
      • 1970-01-01
      相关资源
      最近更新 更多