Javascript 开玩笑地模仿承诺模仿模块工厂

Javascript 开玩笑地模仿承诺模仿模块工厂,javascript,unit-testing,jestjs,Javascript,Unit Testing,Jestjs,我正在编写一些单元测试,需要模拟文件中的命名导出,但当导出是一个返回承诺的函数时,它似乎不起作用 例如,我有一个位于lib/api.js的模块,它导出一个名为getFoo的函数,该函数本身返回axios.get(“/foo”) 在我的测试中,我想模拟getFoo的返回值,使其成为foo负载的解析承诺,因此我使用模块工厂进行模拟: import * as api from 'lib/api'; jest.mock('lib/api', () => ({ getFoo: jest.fn((

我正在编写一些单元测试,需要模拟文件中的命名导出,但当导出是一个返回承诺的函数时,它似乎不起作用

例如,我有一个位于
lib/api.js
的模块,它导出一个名为
getFoo
的函数,该函数本身返回axios.get(“/foo”)

在我的测试中,我想模拟
getFoo
的返回值,使其成为foo负载的解析承诺,因此我使用模块工厂进行模拟:

import * as api from 'lib/api';
jest.mock('lib/api', () => ({
  getFoo: jest.fn(() => Promise.resolve('foo')),
});
然后在我的测试中,我想断言getFoo是作为链接承诺的更大过程的一部分调用的

it('getBar should call getFoo', () => {
  return getBar().then(() => {
    expect(api.getFoo).toHaveBeenCalled();
  });
})
我在这里得到的错误是
无法读取未定义的
的属性'then',就好像模拟模块工厂中使用的jest函数没有返回承诺一样

如果
getFoo
的返回值不是一个承诺,那么它将按预期工作。如果我使用
jest.fn()
作为getFoo的值,然后在测试本身中模拟实现

it('getBar should call getFoo', () => {
  api.getFoo.mockImplementation(() => Promise.resolve("foo"));
  return getBar().then(() => {
    expect(api.getFoo).toHaveBeenCalled();
  });
})
…然后就行了。我的理解是jest.fn(()=>{})应该只是定义实现的一种较短的方法,所以我不确定为什么会出现错误。谢谢你的帮助

谢谢

更多信息:

lib/api
如下所示

import axios from 'axios';

export const getFoo = (host: string, accessToken: string): Promise<{}> =>
  axios.get(`${host}/foo`, {
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
    }
  })
  // return foo
  .then((response) => response.data)
  .catch(() => {
    throw new Error('Failed to load foo');
  });

首先,您需要在导入之前对其进行模拟:

jest.mock('lib/api');

import * as api from 'lib/api';

首先,您需要在导入之前对其进行模拟:

jest.mock('lib/api');

import * as api from 'lib/api';

感谢您的回复,我尝试在之后移动导入,但似乎没有改变结果。我甚至没有在测试文件本身中使用
lib/api
,所以我可能根本不需要导入它,但不管怎样,我得到了相同的错误
无法读取未定义的
属性。你能添加你在
lib/api
中导出的内容吗?看起来您可能没有导出您试图访问的内容。我刚刚注意到您的实现中有一个输入错误,但这很奇怪,因为它会返回一个错误:
getFoo:jest.fn(()=>Promise.resolve('foo'))
。您缺少一个右括号。很抱歉,我已经修复了它,上面的代码我只是手动输入的,而不是从projectLet中复制+粘贴。感谢您的回复,我尝试在之后移动导入,但似乎没有改变结果。我甚至没有在测试文件本身中使用
lib/api
,所以我可能根本不需要导入它,但不管怎样,我得到了相同的错误
无法读取未定义的
属性。你能添加你在
lib/api
中导出的内容吗?看起来您可能没有导出您试图访问的内容。我刚刚注意到您的实现中有一个输入错误,但这很奇怪,因为它会返回一个错误:
getFoo:jest.fn(()=>Promise.resolve('foo'))
。您缺少一个右括号。很抱歉,我已经修复了它,上面的代码我只是手工输入的,而不是从projectLet中复制+粘贴。