Jestjs 用SpyOn进行玩笑测试

Jestjs 用SpyOn进行玩笑测试,jestjs,Jestjs,如何使用spyOn测试这段代码?有人能帮我找到一个合适的解决办法吗 const controller = {}; controller.fetchCars = async (req, res) => { const result = await getCarsService(req.body); res.json(result); }; 我试过这个: it('fetchCars should call getCarsService', () => {

如何使用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();
    });
并给我这个错误:无法监视getCarsService属性,因为它不是函数;未定义,请改为给定

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;
};

最简单的解决方案是将代码分离到每个文件中,然后使用
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);
});

这个问题不包含最重要的部分,即getCarsService的来源。错误说明了问题所在,你无法在它不属于的随机对象上发现它。我编辑了这篇文章,getCarsService看起来如上所述。问题已经更新,它已经在另一个模块中。我尝试了你的解决方案,它给了我这个错误:“无法在原语值上发现;未定义给定”。知道我做错了什么吗?@Christian您是否已将
getCarsService
导出为默认导出?你需要直接按照上面提供的设置进行操作,否则它将不起作用。嗯,我想我不能将其导出为默认设置,因为它不是唯一可用的服务,还有4个服务,我在index.spec.js中尝试了您的解决方案,它给了我上述错误。@Christian您需要重新构造处理服务的方式,例如,将服务分离为一个文件或将其组合为一个对象,然后将其导出为默认导出。已经为您提供了解决方案。