【问题标题】:Jest test with SpyOnSpyOn 的玩笑测试
【发布时间】:2020-11-14 06:10:14
【问题描述】:

如何使用 spyOn 开玩笑地测试这段代码?有人可以帮我找到合适的解决方案吗?

const controller = {};

controller.fetchCars = async (req, res) => {
  const result = await getCarsService(req.body);
  res.json(result);
};

我试过这个:

    it('fetchCars should call getCarsService', () => {
      const spy = jest.spyOn(carsController, 'getCarsService').mockImplementation(() => {});
      const req = {};
      const res = {};

      carsController.fetchCars(req, res);
      expect(spy).toBeCalled()
      spy.mockRestore();
    });

然后给我这个错误:Cannot spy the getCarsService property because it is not a function;改为未定义

getCarsService() 它是从 /services 导入的,它看起来像这样:

export const getCarsService = async body => {
  const carsReqConfig = {
    headers: fetchApi.newHeaderWithToken(CAR_JWT, SITE_ID)
  };
  const result = await instance.post(
    `${API_GATEWAY_URL}${CAR_ENDPOINT}/search`,
    body,
    carsReqConfig
  );
  const cars = result?.data?.results.filter(
    car => car.orderType === 'AI'
  );
  const formatedResponse = formatCarSearchRes(cars);
  return formatedResponse;
};

【问题讨论】:

  • 该问题不包含最重要的部分,即 getCarsService 的来源。错误说明出了什么问题,你不能在它不属于的随机对象上窥探它。
  • 我已经编辑了这篇文章,getCarsService 看起来像上面

标签: jestjs


【解决方案1】:

最简单的解决方案是将您的代码分成每个文件,然后使用jest.mock 模拟 getCarsService 方法。

index.js

import getCarsService from './getCarsService';

const controller = {
    fetchCars: async (req, res) => {
        const result = await getCarsService(req.body);
        return res.json(result);
    },
};

export default controller;

getCarsService.js

function getCarsService(body) {
    return new Promise(resolve => resolve(1));
}

export default getCarsService;

index.spec.js

import controller from './index';
import getCarsService from './getCarsService';

jest.mock('./getCarsService', () => jest.fn().mockResolvedValue(1));

it('fetchCars should call getCarsService', async () => {
    const req = {
        hello: 'world',
    };
    const res = {
        json: jest.fn(),
    };

    await controller.fetchCars(req, res);
    expect(getCarsService).toBeCalled();
    expect(res.json).toBeCalledWith(1);
});

如果您对使用间谍一无所知,您可以通过监视默认导出来做到这一点。

import controller from './index';
import * as getCarsService from './getCarsService';

it('fetchCars should call getCarsService', async () => {
    const req = {
        hello: 'world',
    };
    const res = {
        json: jest.fn(),
    };

    const spy = jest.spyOn(getCarsService, 'default');
    spy.mockResolvedValue(2);

    await controller.fetchCars(req, res);
    expect(res.json).toBeCalledWith(2);
});

【讨论】:

  • 问题已更新,已在另一个模块中。
  • 我尝试了您的解决方案,但它给了我这个错误:“无法监视原始值;未定义给定”。任何想法我做错了什么?
  • @Christian 您是否将getCarsService 导出为默认导出?您需要直接按照上面提供的设置进行操作,否则将无法正常工作。
  • hmm 我想我不能将它导出为默认值,因为它不是唯一可用的服务,还有 4 个服务,我从 index.spec.js 尝试了你的解决方案,它给了我上述错误..
  • @Christian 您将需要重组处理服务的方式,例如通过将它们分成一个文件或将它们组合成一个对象,然后将它们导出为默认导出。解决方案已经提供给您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-28
  • 2021-02-10
  • 2020-07-31
  • 1970-01-01
  • 1970-01-01
  • 2018-01-29
  • 2020-02-06
相关资源
最近更新 更多