首页 > 解决方案 > 我试图从服务中模拟一个函数,但 Jest 一直在调用实际函数而不是模拟函数

问题描述

我正在使用 Jest 来测试使用 axios 进行一些 api 调用的服务中的函数。问题是 Jest 不断调用实际的服务函数而不是模拟的服务函数。以下是所有代码:

测试:

// __tests__/NotificationService.spec.js
const mockService = require('../NotificationService').default;

beforeEach(() => {
  jest.mock('../NotificationService');
});

describe('NotificationService.js', () => {
  it('returns the bell property', async () => {
    expect.assertions(1);
    const data = await mockService.fetchNotifications();
    console.log(data);
    expect(data).toHaveProperty('data.bell');
  });
});

模拟:

// __mocks__/NotificationService.js
const notifData = {
  bell: false,
  rollups: [
    {
      id: 'hidden',
      modifiedAt: 123,
      read: true,
      type: 'PLAYLIST_SUBSCRIBED',
      visited: false,
      muted: false,
      count: 3,
      user: {
        id: 'hidden',
        name: 'hidden'
      },
      reference: {
        id: 'hidden',
        title: 'hidden',
        url: ''
      }
    }
  ],
  system: [],
  total: 1
};

export default function fetchNotifications(isResolved) {
  return new Promise((resolve, reject) => {
    process.nextTick(() =>
      isResolved ? resolve(notifData) : reject({ error: 'It threw an error' })
    );
  });
}

服务:

import axios from 'axios';

// hardcoded user guid
export const userId = 'hidden';

// axios instance with hardcoded url and auth header
export const instance = axios.create({
  baseURL: 'hidden',
  headers: {
    Authorization:
      'JWT ey'
  }
});

/**
 * Notification Service
 * Call these methods from the Notification Vuex Module
 */
export default class NotificationService {

  /**
   * @GET Gets a list of Notifications for a User
   * @returns {AxiosPromise<any>}
   * @param query
   */
  static async fetchNotifications(query) {
    try {
      const res = await instance.get(`/rollups/user/${userId}`, {
        query: query
      });
      return res;
    } catch (error) {
      console.error(error);
    }
  }
}

我尝试了几种使用 require 而不是导入 NotificationService 的变体,但它给出了其他一些神秘的错误......

我觉得我错过了一些简单的东西。

请帮帮我 :)

标签: unit-testingjestjsaxios

解决方案


问题是 Jest 不断调用实际的服务函数而不是模拟的服务函数。

babel-jest提升jest.mock调用,以便它们在其他所有内容(甚至import调用)之前运行,但提升是代码块的本地,issue 2582中所述。

我觉得我错过了一些简单的东西。

将您的jest.mock呼叫移到外部beforeEach,它将被提升到整个测试的顶部,因此您的模拟由以下方式返回require

const mockService = require('../NotificationService').default;  // mockService is your mock...

jest.mock('../NotificationService');  // ...because this runs first

describe('NotificationService.js', () => {
  it('returns the bell property', async () => {
    ...
  });
});

推荐阅读