简体   繁体   English

在运行摩卡单元测试时,如何避免在NodeJS回调样式API中两次调用Q promise catch块?

[英]How can I avoid my Q promise catch block being called twice in a NodeJS callback-style API when running mocha unit tests?

We're using the Q promise library in our node API, but allow functions to be called via callbacks. 我们在节点API中使用了Q Promise库,但是允许通过回调调用函数。

For example: 例如:

function foo(cb) {
 Q.fcall(function () {
    return true;
 }).then(function (result) {
    return cb(null, result);
 }).catch(function (err) {
    return cb(err, null);
 });
}

When I run my mocha unit tests, if there is an exception in the callback , it results in the the callback being called twice. 当我运行mocha单元测试时,如果回调中存在异常,则会导致回调被调用两次。

For example: 例如:

var called = 0;
foo(function (err, res) {
  called++;
  console.log('err: ' + err);
  console.log('res: ' + res);
  console.log('called: ' + called);

  throw Error(throw Error from foo!');
});

This gives the following result: 得到以下结果:

err: null res: true called: 1 err: Error: throw Error from foo! err:null res:真调用:1 err:错误:foo抛出错误! res: null called: 2 res:null称为:2

One approach we found was to do the following: 我们发现的一种方法是执行以下操作:

function foo2(cb) {
 var _result, _err;
 Q.fcall(function () {
     return true;
  }).then(function (result) {
     _result = result;
  }).catch(function (err) {
     _err = err;
  }).finally(function () {
     _.defer(cb, _err, _result);
  });
}

The idea was to have one place where the callback would be called and try to prevent developer errors by enforcing the defer to clear the call stack. 想法是在一个地方可以调用回调,并通过强制延迟清除调用堆栈来防止开发人员出错。

With this approach, our callback is called once, and any errors (or in our case, asserts) get handled directly by the caller. 使用这种方法,我们的回调将被调用一次,并且任何错误(在我们的情况下是断言)都将由调用方直接处理。

Is there a better technique we can use? 有没有更好的技术可以使用? I feel like this is a pretty common scenario, so I'd imagine there exists a cleaner solution... 我觉得这是一个很常见的情况,所以我想有一个更清洁的解决方案...

Modify your foo function to handle both the fulfillment and the rejection in the same then call using 2 separate handlers: 修改foo函数,以同时处理实现和拒绝, then使用2个单独的处理程序then调用:

function foo(cb) {
 Q.fcall(function () {
    return true;
 }).then(function (result) {
    return cb(null, result);
 }, function (err) {
    return cb(err, null);
 });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 单元测试失败时调用两次回调 - callback being called twice when my unit test fails 如何链接Promises和回调样式代码 - How to chain Promises and callback-style code 防止“Uncaught (in promise)”警告。 如何避免'catch'块? ES6 承诺与 Q 承诺 - Prevent of “Uncaught (in promise)” warning. How to avoid of 'catch' block? ES6 promises vs Q promises NodeJS Q Promise捕获从未用护照JS调用 - Nodejs Q promise catch never called with passport js 如何按顺序执行异步Mocha测试(NodeJS)? - How can I execute async Mocha tests (NodeJS) in order? IntelliJ IDEA:当 Karma 和 Mocha 都安装时,我可以直接用 Mocha 运行“绿色箭头”单元测试吗? - IntelliJ IDEA: Can I run “green arrow” unit tests directly with Mocha, when both Karma and Mocha are installed? NodeJS promise(Q).then not named - NodeJS promise (Q) .then its not called 如何确保我的函数被调用并正在运行 - How can I ensure that my function is being called and running 运行jasmine测试时,我怎么知道我是否在一个描述块中,在每个块之前还是阻塞? - When running jasmine tests, how can I know if I am in a describe block, beforeEach block or it block? 如何避免在 Promise 中重复捕获 function - How can I avoid repeat catch function in Promise
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM