不同的 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 第二次调用)。
我的问题是:
- 是否有可能在我的机器上和 CI,Mocha 使用不同的 promise 实现?
- 有没有办法强制实现 Mocha 的承诺?
- 也许更改的 Promise 来自代码中的另一个地方?
所有这些看起来真的很奇怪,尤其是当代码使用 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
可能会通过,但这只是运气,因为承诺并不能保证它会起作用。这种运气可能会改变,如果:
您切换到不同的承诺实现。
您 运行 在不同的平台上。 Promise 实现必须与各种平台提供的功能一起工作。因此,在不同平台之间的行为可能会有所不同,这很好,只要它不违反规范即可。但是,您的初始代码所依赖的行为不受规范的保证,因此它可能不会在所有平台上得到维护。
您使用的 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?
不确定你的意思。
我最近遇到了一个奇怪的行为。我有一个包含大量测试的大项目,其中一些测试是以同步方式编写的,假设 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 第二次调用)。
我的问题是:
- 是否有可能在我的机器上和 CI,Mocha 使用不同的 promise 实现?
- 有没有办法强制实现 Mocha 的承诺?
- 也许更改的 Promise 来自代码中的另一个地方?
所有这些看起来真的很奇怪,尤其是当代码使用 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
可能会通过,但这只是运气,因为承诺并不能保证它会起作用。这种运气可能会改变,如果:
您切换到不同的承诺实现。
您 运行 在不同的平台上。 Promise 实现必须与各种平台提供的功能一起工作。因此,在不同平台之间的行为可能会有所不同,这很好,只要它不违反规范即可。但是,您的初始代码所依赖的行为不受规范的保证,因此它可能不会在所有平台上得到维护。
您使用的 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?
不确定你的意思。