【问题标题】:Subclassing and extending Promise for Jest mock为 Jest 模拟子类化和扩展 Promise
【发布时间】:2020-06-14 09:20:03
【问题描述】:

我正在使用模块 rn-fetch-blob 来管理 React-Native 项目中的下载。该模块提供了一个StatefulPromise 类,它基本上是一个带有一些附加功能的承诺。这个添加的功能给我的 Jest 单元测试带来了问题。这是最初导致问题的模拟(文件 __mocks__/rn-fetch-blob.js 中的代码):

export default {
  config: jest.fn(x => {
    return {
      fetch: jest.fn(x => Promise.resolve({  // <- I believe the problem lies here
        info: () => {
          return {status: 200}
        }
      }))
    }
  })
}

在我的代码中某处,我引用了 StatefulPromise 方法之一 (expire)。涵盖该方法的单元测试失败并显示以下消息: filePromise.expire is not a function.

我的想法是创建自己的StatefulPromise以进行测试:

class StatefulPromise extends Promise {
  expire() {
    jest.fn(() => {})
  }
}

...
...
...
      fetch: jest.fn(x => StatefulPromise.resolve({<same logic as before>});

这并没有解决问题。

我会注意到这在我的浏览器 javascript 控制台中似乎工作得很好。以下内容也让我感到惊讶:

let foo = StatefulPromise.resolve('foo');
console.log(foo instanceof StatefulPromise);
// true in console; false in jest

这让我很困惑。有没有更好的方法来解决这个问题?

【问题讨论】:

    标签: javascript react-native unit-testing jestjs rn-fetch-blob


    【解决方案1】:

    如果类继承出错,StatefulPromise.resolve('foo') instanceof StatefulPromise 可能为假。如果它在某些环境中工作但在 Jest 中不起作用,这可能意味着 Jest 没有正确配置,并且类继承在不应该受到 Babel 影响时受到影响。这不一定是这个测试的问题,但以后可能会成为问题。

    rn-fetch-blobdoesn't provide custom methods with inheritance。即使可以,这通常也不会要求在测试中复制类层次结构。正如源代码中所建议的那样,无需在随时间变化的测试中使用第三方StatefulPromise。由于 promise 应该表现得像 ES6 promise,因此可以用它来模拟它并在需要时对其进行扩充。

    是:

      fetch: jest.fn(x => Object.assign(
        Promise.resolve(...),
        { extend: jest.fn() }
      )
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    相关资源
    最近更新 更多