javascript - Node.js 如何使用 mocha 为异步测试获取更好的错误消息

标签 javascript node.js asynchronous mocha.js

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

 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 () 永远不会被调用。对于以前没有使用过测试套件的人来说,这会留下一个不明确的错误,例如:

错误:超时超过 10500 毫秒。确保在此测试中调用done()回调。

我的问题是,有没有办法重写这些测试,无论是使用 mocha 还是除了另一个库之外,都可以使像这样的异步工作更容易遵循。我希望能够输出如下内容:

调用clients.event.on(...)后从未调用回调doneFn()

或者类似的东西。

我不确定使用诸如 promise 之类的东西是否会有所帮助。对于异步/回调类型代码来说,更有意义的错误消息将是一件很棒的事情。如果这意味着从回调/异步转移到另一个工作流程,我也同意。

有哪些解决方案?

最佳答案

当您收到超时错误而不是更精确的错误时,要做的第一件事是检查您的代码是否不会吞咽异常,并且不会吞咽 promise 拒绝。 Mocha 是旨在在您的测试中检测这些。除非您做了一些不寻常的事情,例如在自己的虚拟机中运行测试代码或操作 domains ,Mocha 会检测到此类故障,但如果您的代码吞噬了它们,Mocha 将无能为力。

话虽这么说,Mocha 将无法告诉您 done 未调用,因为您的实现存在逻辑错误,导致其无法调用回调。

以下是使用 sinon 可以在测试失败后执行事后分析的方法。让我强调一下,这是一个概念证明。如果我想持续使用它,我会开发一个合适的库。

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;

关于javascript - Node.js 如何使用 mocha 为异步测试获取更好的错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38083994/

相关文章:

javascript - 使用 AJAX 验证网址

android - 使用 appium Node 服务器在模拟器上安装 Android APK

node.js - docker : React App doesn't read environment variable

javascript - 如何在函数中执行异步工作,然后在完成后从该函数返回一个值?

javascript - 三星智能电视、PlayDRM 和 HLS

javascript - 如何在 JavaScript 中将字符串中每个单词的第一个字母大写并将所有空格更改为下划线

javascript - 用动画上下滑动 table

node.js - Node.js 和 socket.io 的 Redis 身份验证错误

ios - Swift:在不同的函数中调用闭包完成方法

ios - AFNetworking 同步调用(类似/不同)