【发布时间】:2016-09-26 00:47:47
【问题描述】:
好的,我的设置如下: 使用 node 6.2、es6-promisify、sinon、sinon-as-promised 和 babel 转译对 es6 导入/导出的支持。
我的测试代码如下所示:
const client = restify.createJsonClient({
url: 'http://www.example.com'
});
export let get = promisify(client.get, {thisArg: client, multiArgs: true});
export default function* () {
yield get('/some/path');
}
然后在我的测试文件中我有这样的东西:
import * as m from mymodule;
it('should fail', function(done) {
let stub = sinon.stub(m, 'get').rejects('i failed');
client.get('/endpoint/that/leads/to/mymodule/call', function(err, req, res, data) {
stub.called.should.be.eql(true); // assertion fails!!
done();
}
});
我也尝试过对原始的 client.get 调用存根,但这也不起作用。我唯一要做的就是在每次调用时即时做出承诺,并将原始的 client.get 存根,这看起来很蹩脚。例如:
export const client = restify.createJsonClient({
url: 'http://www.example.com'
});
function get() {
return promisify(client.get, {thisArg: client, multiArgs: true});
}
export default function* () {
yield get('/some/path');
}
然后测试代码:
import {module_client} from mymodule;
it('should fail', function(done) {
let stub = sinon.stub(module_client, 'get').yields('i failed');
client.get('/endpoint/that/leads/to/mymodule/call', function(err, req, res, data) {
stub.called.should.be.eql(true); // assertion succeeds
done();
}
});
所以问题是,如果不是很明显,为什么我的原始代码不起作用?有没有办法让存根工作而不用每次都承诺原始的restify(例如,其他人如何让这种事情工作)?
编辑:
当前代码如下所示:
const client = restify.createJsonClient({
url: 'http://www.example.com'
});
export let get = promisify(client.get, {thisArg: client, multiArgs: true});
export default function*() {
try {
console.log(exports.get); // <= a large sinon stub object, I'll post that below
yield exports.get(); // <= throws here, "exports.get is not a function"
}
catch(ex) {
log.error('got an error', ex);
throw ex;
}
}
console.log 打印以下内容:
{ [Function: proxy]
isSinonProxy: true,
reset: [Function],
invoke: [Function: invoke],
named: [Function: named],
getCall: [Function: getCall],
getCalls: [Function],
calledBefore: [Function: calledBefore],
calledAfter: [Function: calledAfter],
withArgs: [Function],
matches: [Function],
printf: [Function],
calledOn: [Function],
alwaysCalledOn: [Function],
calledWith: [Function],
calledWithMatch: [Function],
alwaysCalledWith: [Function],
....
EDIT2:
FWIW,babel 生成的代码正在生成:
let get = exports.get = (0, _es6Promisify2.default)(client.get, { thisArg: client, multiArgs: true });
EDIT3:
好吧,超级奇怪。我改变了我的来源来做到这一点:
const client = restify.createJsonClient({
url: 'http://www.example.com'
});
export let get = promisify(client.get, {thisArg: client, multiArgs: true});
export default function*() {
try {
let thePromise = exports.get(); // e.g. call exports.get on separate line from the yield
yield thePromise; // and the throw now says 'undefined is not a function'. I should note that in both cases, the stack trace shows the error on node_modules/co/index.js at line 65.
}
catch(ex) {
log.error('got an error', ex);
throw ex;
}
}
【问题讨论】:
-
get()未导出,因此module_client.get()在您的测试代码中未定义。但即使它被导出,仍然存在由 ES6 引起的问题(至少,我认为)。我会看看我能不能写出来作为答案。 -
如果你的意思是'get'没有在第二个例子中被导出,你是对的,我确实有一个错误。我的意思是,原来的 restify.client 被导出为 module_client。我正在扼杀它。哪个有效。
-
哦,对不起,当然是!我的回答应该仍然适用于第一种情况,第二种情况通过在运行时而不是在导入时进行承诺来解决它。
标签: javascript testing ecmascript-6 sinon es6-promise