不同的Mocha行为 - 异步/同步承诺

时间:2017-07-13 12:56:23

标签: node.js testing promise mocha bluebird

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

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

// 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 mock会在两次调用后恢复。如果异步调用promise,则第一次调用成功,但第二次调用失败,同时恢复存根( 第二次调用之前)。

我的问题是:

  • 有可能在我的机器和CI上,Mocha使用不同的承诺实现吗?
  • 有没有办法强制实施Mocha的承诺?
  • 也许改变后的Promise来自代码中的另一个地方?

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

1 个答案:

答案 0 :(得分:1)

如果你所测试的内容在保证解决之前不能保证处于正确的测试状态,那么你应该在你的第二个片段中显示你的测试。 是测试依赖于已解决的承诺的条件的正确方法。您的初始代码工作的事实是由于运气。请考虑以下代码:

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中的承诺立即得到解决,但无所谓。 test one失败了,因为我不等待承诺。如果我使用Bluebird或Node的库存Promise实现无关紧要。

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

  1. 您切换到其他承诺实施。

  2. 您在不同的平台上运行。承诺实现必须与各种平台提供的一致。因此,从平台到平台可能会有所不同,这很好,只要它不违反规范。但是,您的初始代码所依赖的行为不符合规范,因此可能无法在所有平台上维护。

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

  4.   

    有可能在我的机器和CI上,Mocha使用不同的promise实现吗?

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

      

    有没有办法强制实施Mocha的承诺?

    见上文。它接收您返回的承诺,因此它使用您在测试套件中使用的任何实现。

      

    也许改变后的Promise来自代码中的另一个地方?

    不确定你的意思。