【问题标题】:How do I get Promises to work when using Jest CLI?使用 Jest CLI 时如何让 Promises 工作?
【发布时间】:2015-07-06 00:44:33
【问题描述】:

我正在尝试使用 Jest CLI 测试一个 Promise,此代码在浏览器中运行时会按应有的方式执行。但是我想开始为它编写测试。

class ListCollection {
  constructor() { 
    this.items = new Array();
  }

  addItem(string) {
    const addItemPromise = new Promise(
      function (resolve, reject) {
        // set up async getting like a XMLHttpRequest
        setTimeout( () => {
          this.items.push(string);
          resolve(string);
        }.bind(this), 2000);
      }.bind(this)
    );
    return addItemPromise;
  }
}

目前我正在尝试让这个非常基本的测试工作。我正在根据documentation which links to jasmine-pit 使用pit 进行测试。

jest.dontMock('../collections');

import Collection       from '../collections';

describe("Collection", () => {
    let collection;

    beforeEach(() => {
        collection = new Collection();
    });

    describe("Adding an item", () => {
        pit('Spec 1', function () {
            return collection.addItem("Hello World").then(function (string) {
                expect(string).toBe("Hello World");
            });
        });
    });
})

当我使用babel-node ./node_modules/.bin/jest 运行测试时,上面的测试失败了,因为它是堆栈跟踪。值得注意的是,我得到了Promise is not defined

Rollos-Mac-Pro:react-boilerplate Rollo$ babel-node ./node_modules/.bin/jest
Using Jest CLI v0.4.0
 FAIL  app/collections/__tests__/collectionTests.js
ReferenceError: /Users/Rollo/react-boilerplate/app/collections/__tests__/collectionTests.js: /Users/Rollo/react-boilerplate/app/collections/collections.js: **Promise is not defined**
    at ListCollection.addItem (/Users/Rollo/react-boilerplate/app/collections/collections.js:24:34)
    at /Users/Rollo/react-boilerplate/app/collections/collections.js:48:12
    at Object.runContentWithLocalBindings (/Users/Rollo/react-boilerplate/node_modules/jest-cli/src/lib/utils.js:361:17)
    at Loader._execModule (/Users/Rollo/react-boilerplate/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:250:9)
    at Loader.requireModule (/Users/Rollo/react-boilerplate/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:916:12)
    at Loader.requireModuleOrMock (/Users/Rollo/react-boilerplate/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:937:17)
    at /Users/Rollo/react-boilerplate/app/collections/__tests__/collectionTests.js:7:34
    at Object.runContentWithLocalBindings (/Users/Rollo/react-boilerplate/node_modules/jest-cli/src/lib/utils.js:361:17)
    at Loader._execModule (/Users/Rollo/react-boilerplate/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:250:9)
    at Loader.requireModule (/Users/Rollo/react-boilerplate/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:916:12)
    at jasmineTestRunner (/Users/Rollo/react-boilerplate/node_modules/jest-cli/src/jasmineTestRunner/jasmineTestRunner.js:242:16)
    at /Users/Rollo/react-boilerplate/node_modules/jest-cli/src/TestRunner.js:371:12
    at _fulfilled (/Users/Rollo/react-boilerplate/node_modules/jest-cli/node_modules/q/q.js:798:54)
    at self.promiseDispatch.done (/Users/Rollo/react-boilerplate/node_modules/jest-cli/node_modules/q/q.js:827:30)
    at Promise.promise.promiseDispatch (/Users/Rollo/react-boilerplate/node_modules/jest-cli/node_modules/q/q.js:760:13)
    at /Users/Rollo/react-boilerplate/node_modules/jest-cli/node_modules/q/q.js:574:44
    at flush (/Users/Rollo/react-boilerplate/node_modules/jest-cli/node_modules/q/q.js:108:17)
    at /Users/Rollo/react-boilerplate/node_modules/jest-cli/src/lib/FakeTimers.js:325:7
    at process._tickCallback (node.js:448:13)

我不知道如何解决这个问题。我使用的节点版本必须是 0.10.x,否则我无法运行 Jest-CLI。但是节点版本 0.10.x 没有承诺。我也不明白 Jest-CLI 如何与我的 ES6 类和语法一起工作,但无法识别 Promises。

知道如何让 Promise 在我的设置中发挥作用吗?

编辑

我已将es6-promise polyfill 添加到我的测试文件的顶部,并将其标记为不被模拟。这提供了适当的修复。

jest.dontMock('es6-promise');
require('es6-promise').polyfill();

【问题讨论】:

  • 升级节点对我有用。节点版本 12.7 解决了这个问题

标签: javascript node.js jasmine reactjs jestjs


【解决方案1】:

输出中提到了babel-node,这意味着babel 作为一个require hook 运行,将你的ES6 编译成ES5。您需要为原生 Promise 包含一个 shim,并将其公开为 global.Promise。我推荐这个:https://github.com/jakearchibald/es6-promise

【讨论】:

  • 我实际上在使用 vanilla 节点时得到了相同的堆栈跟踪。那么如果 babel 将 ES6 转换为 ES5,为什么 promises 没有 polyfill?感谢您的链接,我将把它放到我的测试文件中,看看它是否能解决我的问题。将更新:-)
  • 可以告诉 Babel 为 Promise 等 ES6 功能提供 polyfill。我的印象是 babel-node 默认包含它,但我不确定。
  • 我也有这种印象,但是据说 Jest 和 Jasmine 做了很多奇怪的事情,运行时可能会搞砸。
  • 包含 polyfill 有帮助,但 promise 对象没有返回任何我在文件开头包含 require('es6-promise').polyfill() 的内容,但现在测试超时了。为了更好地衡量,我还确保jest.dontMock('es6-promise');
  • 编辑,你的答案是正确的,我没有意识到这一点,但 settimeout 被嘲笑了。
【解决方案2】:

用 babel-jest 替换 jest scriptPreprocessor 应该适用于所有 es6 可比性问题

https://babeljs.io/docs/using-babel/#jest

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多