不同的 Mocha 行为 - async/sync promises

Different Mocha behaviour - async/sync promises

我最近遇到了一个奇怪的行为。我有一个包含大量测试的大项目,其中一些测试是以同步方式编写的,假设 promise 库是没有 deferred 的那个。

然而,在我的机器上准备好环境后(Mac OS X,nodeJS 0.12.18 - 我知道 :( ),测试似乎 运行 有不同promise 实现 - 这次使用带有延迟的异步版本,因此以下测试失败:

// Some generic mocking code here

instance.doSomething(); // This returns a promise

// Immediately after the previous call, we check the results and clean mocks
sinon.assert.called(request.Request);
request.Request.restore();

改写后开始运行:

return instance.doSomething().then(function() {
  sinon.assert.called(request.Request);
  request.Request.restore();
});

综上所述,instance.doSomething 执行了两个请求。

如果 promise 被同步调用,request 模拟将在 两次调用后恢复。如果异步调用 promise,则第一次调用成功但第二次失败,因为同时存根已恢复(before 第二次调用)。

我的问题是:

所有这些看起来真的很奇怪,尤其是当代码使用 bluebird 作为主要的 Promise 库时...

如果在 promise 得到解决之前无法保证您正在测试的内容处于正确的测试状态,那么您应该按照第二个代码段中所示的那样编写测试。 That 是测试依赖于已解决承诺的条件的正确方法。您的初始代码之所以有效,是因为运气。考虑以下代码:

const assert = require("assert");
const Promise = require("bluebird");

let moo = "initial";

function someFunc() {
    return Promise.resolve()
        .then(function () {
            moo = "modified";
        });
}

beforeEach(() => moo = "initial");

it("test one", () => {
    someFunc();
    assert.equal(moo, "modified");
});

it("test two", () => {
    return someFunc().then(() => {
        assert.equal(moo, "modified");
    });
});

someFunc中的promise马上resolve了,不过没关系。 test one 失败,因为我没有等待承诺。我使用 Bluebird 还是 Node 的现有 Promise 实现并不重要。

在某些情况下 test one 可能会通过,但这只是运气,因为承诺并不能保证它会起作用。这种运气可能会改变,如果:

  1. 您切换到不同的承诺实现。

  2. 您 运行 在不同的平台上。 Promise 实现必须与各种平台提供的功能一起工作。因此,在不同平台之间的行为可能会有所不同,这很好,只要它不违反规范即可。但是,您的初始代码所依赖的行为不受规范的保证,因此它可能不会在所有平台上得到维护。

  3. 您使用的 promise 实现的新版本已发布,不再保持您所依赖的行为。

Is is possible that on my machine and CI, Mocha uses different promise implementations?

查看 Mocha 的代码,我没有看到 Mocha 实例化承诺的任何位置。它检测 it return 是否是一个承诺,并依赖于承诺提供的 API 但它不会创建自己的承诺。

Is there a way to force promise implementation for Mocha?

见上文。它收到你的承诺 return 所以它使用你在测试套件中使用的任何实现。

Maybe the changed Promise comes from another place in the code?

不确定你的意思。