我有一段时间试图通过基本的http测试来处理誓言。
我想我已经遵循vows http://vowsjs.org/#-writing-asynchronous-tests的异步示例并取代了相应的调用,但我必须遗漏一些东西。
测试代码如下所示:
var http = require('http'),
vows = require('vows'),
assert = require('assert');
vows.describe("homepage").addBatch({
"Get the home page": {
topic: function() {
http.get({'host': "127.0.0.1", 'port': 5000, 'path': '/'}, this.callback);
},
'should respond with 200 OK': function(res) {
assert.equal(res.statusCode, 200);
}
}
}).export(module);
当我尝试为此运行测试时出现以下错误:
/Users/<home_folder>/node_modules/vows/lib/vows.js:80
rrored', { type: 'promise', error: err.stack || err.message || JSON.stringify(
^
TypeError: Converting circular structure to JSON
at Object.stringify (native)
at EventEmitter.<anonymous> (/Users/<home_folder>/node_modules/vows/lib/vows.js:80:90)
at EventEmitter.emit (events.js:64:17)
at /Users/<home_folder>/node_modules/vows/lib/vows/context.js:31:52
at ClientRequest.<anonymous> (/Users/<home_folder>/node_modules/vows/lib/vows/context.js:46:29)
at ClientRequest.g (events.js:143:14)
at ClientRequest.emit (events.js:64:17)
at HTTPParser.onIncoming (http.js:1349:9)
at HTTPParser.onHeadersComplete (http.js:108:31)
at Socket.ondata (http.js:1226:22)
我可以得到一个简单的http示例来自行处理它。我可以得到誓言的例子来处理它自己,但我不能因为某种原因将它们结合起来。我真的很感激这里的一些帮助。我一直试图让它工作一段时间(包括谷歌搜索)。
更新
显然在回调中添加错误参数解决了这个问题,感谢Alexis Sellier(誓言的创造者)的帮助。
但我不明白为什么。当写出自己的http lib示例时,不需要错误参数。我无法在誓言中找到任何文件来说明为什么需要它,所以我有点不知所措。
我的新问题是为什么在vows中使用http lib时需要使用错误参数?
答案 0 :(得分:4)
检查誓言的源代码后,我想我知道为什么。 Vows始终确保在调用this.callback
时,生成的接收函数的第一个参数始终是错误对象。誓言通过以下规则解释回调:
如果您的原始回调的第一个参数是布尔值,请使用它来确定是否将错误对象附加到接收回调(例如,path.exists(boolean)
将发出callback(error, exists)
代替)
如果第一个参数是一个对象,则假设它是一个错误对象,并使用它来确定是否将原始回调添加到“错误”或“成功”列表中。这个列表存在的原因是支持基于承诺的测试吗?
虽然我无法确认上述内容是否正确,但我的经验是誓言的异步样式是为了支持节点样式的回调(例如err作为第一个arg),以及第三方npm模块不符合这个标准很难测试。
请不要将我的答案视为福音,因为这是我自己的经历。另一个问题是当您在要测试的函数内部进行异步操作时 - 除非您提供回调,否则vows将无法正确处理它。
就个人而言,我认为誓言仍然难以测试异步代码。我希望它有一些waitFor()
或until()
流量控制功能。
我的建议?处理异步代码时,请使用Step。不要让誓言控制你的流量。
答案 1 :(得分:1)
文档中实际上缺少这个文档仍然有点短。但你可以在this page中看到它:
'when peeled *asynchronously*': {
topic: function (banana) {
banana.peel(this.callback);
},
'results in a `PeeledBanana`': function (err, result) {
assert.instanceOf (result, PeeledBanana);
}
}
正如Morten Siebuhr和Ruben Tan所说的那样,这就是誓言的工作方式,这就是为什么它会这样运作。