Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/454.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Jest mockImplementation(Promise.resolve)在监视从另一个类(Node.js)调用的对象时返回undefined_Javascript_Node.js_Unit Testing_Async Await_Jestjs - Fatal编程技术网

Javascript Jest mockImplementation(Promise.resolve)在监视从另一个类(Node.js)调用的对象时返回undefined

Javascript Jest mockImplementation(Promise.resolve)在监视从另一个类(Node.js)调用的对象时返回undefined,javascript,node.js,unit-testing,async-await,jestjs,Javascript,Node.js,Unit Testing,Async Await,Jestjs,我很难让Jest Mock实现在特定上下文中返回带有Promise.resolve()的数据 在Node.js代码中,我有一个将所有API调用代码放在一个类(API)中,将所有业务逻辑放在另一个类(Repo)中的结构。当您实例化Repo时,它会为自己创建一个Api类的实例:this.Api=newAPI() 我正在尝试在Repo级别测试一个函数,并模拟Api调用,以便在测试期间不进行任何查询 const data = { postId: 3, id: 3, name: 'Bob Your U

我很难让Jest Mock实现在特定上下文中返回带有Promise.resolve()的数据

在Node.js代码中,我有一个将所有API调用代码放在一个类(API)中,将所有业务逻辑放在另一个类(Repo)中的结构。当您实例化Repo时,它会为自己创建一个Api类的实例:
this.Api=newAPI()

我正在尝试在Repo级别测试一个函数,并模拟Api调用,以便在测试期间不进行任何查询

  const data = { postId: 3, id: 3, name: 'Bob Your Uncle' };
  beforeEach(() => {
    getSpy = jest.spyOn(repo.api, 'getPage').mockImplementation(() => {
      Promise.resolve(data);
    });
  });
当我执行函数时,
expect(getSpy).toHaveBeenCalledTimes(1)
返回true,但它返回的值是“未定义”的,而不是预期的承诺已解析

当我实际运行代码时,它工作正常,但测试失败。我怀疑问题可能与我正在测试的代码正在调用第二个用户编写的类有关,因为我不确定。我发现这个问题似乎有关联,但他们的解决方案(将.prototype添加到spyOn参数中)对我没有帮助——他们使用的是原生JS对象,而不是用户定义的对象,这似乎不同到足以解释差异

下面是完整的
描述
块:

describe('Repo: fetchRand', () => {
  const data = { postId: 3, id: 3, name: 'Bob Your Uncle' };
  beforeEach(() => {
    getSpy = jest.spyOn(repo.api, 'getPage').mockImplementation(() => {
      Promise.resolve(data);
    });
  });
  afterEach(() => {
    jest.clearAllMocks();
  });
  it('should fetch call this.api.getPage once', async () => {
    let res = await repo.fetchRand();
    expect(getSpy).toHaveBeenCalledTimes(1);
  });
  it('should return an object with a postId and an name', async () => {
    let res = await repo.fetchRand();
    expect(res).toHaveProperty('postId');
    expect(res).toHaveProperty('name');
  });
});
以及正在测试的模块:

const Api = require('./Api');

module.exports = class Repository {
  constructor() {
    this.api = new Api();
  }
  async fetchRand() {
    let id = this.getRandomInt(5);
    let res = await this.api.getPage(id);
    return res;
  }
  getRandomInt(max) {
    return Math.floor(Math.random() * max) + 1;
  }
};

还有一个到--run
npm test--Repo.test.js
的链接来复制这个问题。(这不是我真正的项目,只是复制问题基本性质的最简单完整代码。)

来自Estus Flask的评论让我找到了书面答案。我想,这与一流企业中的一流企业毫无关系,只是使用了错误的模拟

这一变化奏效了:

getSpy = jest.spyOn(repo.api, 'getPage').mockResolvedValue(data);

这个问题是特定于JavaScript箭头语法的,而不是玩笑
getPage
spy不返回承诺,因此它返回
undefined

应使用无括号的隐含返回:

.mockImplementation(() => (
  Promise.resolve(data);
));
或显式返回:

.mockImplementation(() => {
  return Promise.resolve(data);
});
返回承诺的spy实现的快捷方式是:

.mockResolvedValue(data);

再次检查语法,它不会返回承诺。还有
mockResolvedValue
可以让意图更加清晰。谢谢@EstusFlask--我不明白为什么它没有回复承诺,但是
mockResolvedValue
对我有效。我不太会开玩笑,我每天都在寻找新的方法来捣乱;)