node.js如何使用mocha为异步测试获取更好的错误消息 [英] node.js how to get better error messages for async tests using mocha

查看:196
本文介绍了node.js如何使用mocha为异步测试获取更好的错误消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的node.js mocha套件中的典型测试如下所示:

A typical test in my node.js mocha suite looks like the following:

 it("; client should do something", function(done) {
    var doneFn = function(args) {
      // run a bunch of asserts on args
      client.events.removeListener(client.events.someEvent, userMuteFn);
      done();
    }

    client.events.on(someEvent, doneFn);

    client.triggerEvent();
});

这里的问题是如果 client.triggerEvent()没有做正确的事,或者如果服务器中断并且从不调用 someEvent ,那么 done()永远不会被援引。这为以前没有使用过测试套件的人留下了一个模棱两可的错误:

The problem here is that if client.triggerEvent() doesn't do something right, or if the server breaks and never invokes someEvent, then done() will never get invoked. This leaves an ambiguous error for someone who hasn't worked with the testsuite before like:

错误:超出了10500ms的超时。确保在此测试中调用done()回调。

我的问题是,有没有办法重写这些测试,无论是否使用mocha或者除了另一个lib之外,这使得像这样的异步工作更容易理解。我希望能够输出如下内容:

My question is, is there a way to rewrite these tests, whether it's with mocha or in addition to another lib, that makes async work like this easier to follow. I'd love to be able to output something such as:

在clients.event.on(。之后从未调用过回调doneFn()。 ..)被调用

或类似的东西。

我是不确定是否使用诸如承诺之类的东西会有所帮助。异步/回调类型代码更有意义的错误消息将是一件好事。如果这意味着从回调/异步转移到另一个工作流程,那我也可以。

I'm not sure if using something such as promises would help this. More meaningful error messages for async/callback type code would be a great thing. If it means moving from callback/async to another workflow, I'm OK with that as well.

有什么解决方案?

推荐答案

当你收到超时错误而不是更准确的错误时,要做的第一件事就是检查你的代码是否不会吞下异常,它不会吞下承诺拒绝。 Mocha旨在在您的测试中检测这些。除非你做一些不寻常的事情,比如在你自己的虚拟机中运行测试代码或操纵,否则摩卡会检测到这样的失败,但如果你的代码吞没了它们,那么Mocha就无法做到。

When you get a timeout error rather than a more precise error, the first thing to do is to check that your code does not swallow exceptions, and that it does not swallow promise rejections. Mocha is designed to detect these in your tests. Unless you do something unusual like running test code in your own VM or manipulate domains, Mocha will detect such failures, but if your code swallows them, there's nothing Mocha can do.

这就是说,Mocha将无法告诉你完成没有被调用,因为你的实现有一个逻辑错误,导致它无法调用回调。

This being said, Mocha won't be able to tell you that done was not called because your implementation has a logic bug that causes it to fail to call the callback.

这是可以做什么的 sinon 在测试失败后执行验尸。让我强调这是概念证明。如果我想持续使用它,我会开发一个合适的库。

Here is what could be done with sinon to perform a post mortem after test failures. Let me stress that this is a proof of concept. If I wanted to use this on an ongoing basis, I'd develop a proper library.

var sinon = require("sinon");
var assert = require("assert");

// MyEmitter is just some code to test, created for the purpose of
// illustration.
var MyEmitter = require("./MyEmitter");
var emitter = new MyEmitter();

var postMortem;
beforeEach(function () {
  postMortem = {
    calledOnce: []
  };
});

afterEach(function () {
  // We perform the post mortem only if the test failed to run properly.
  if (this.currentTest.state === "failed") {
    postMortem.calledOnce.forEach(function (fn) {
      if (!fn.calledOnce) {
        // I'm not raising an exception here because it would cause further
        // tests to be skipped by Mocha. Raising an exception in a hook is
        // interpreted as "the test suite is broken" rather than "a test
        // failed".
        console.log("was not called once");
      }
    });
  }
});

it("client should do something", function(done) {
  var doneFn = function(args) {
    // If you change this to false Mocha will give you a useful error.  This is
    // *not* due to the use of sinon. It is wholly due to the fact that
    // `MyEmitter` does not swallow exceptions.
    assert(true);
    done();
  };

  // We create and register our spy so that we can conduct a post mortem if the
  // test fails.
  var spy = sinon.spy(doneFn);
  postMortem.calledOnce.push(spy);
  emitter.on("foo", spy);

  emitter.triggerEvent("foo");
});

以下是 MyEmitter.js 的代码:

var EventEmitter = require("events");

function MyEmitter() {
    EventEmitter.call(this);
}

MyEmitter.prototype = Object.create(EventEmitter.prototype);
MyEmitter.prototype.constructor = MyEmitter;

MyEmitter.prototype.triggerEvent = function (event) {
    setTimeout(this.emit.bind(this, event), 1000);
};

module.exports = MyEmitter;

这篇关于node.js如何使用mocha为异步测试获取更好的错误消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆