should.js不会导致mocha测试失败

时间:2014-06-05 22:51:52

标签: javascript unit-testing mocha should.js

我是单元测试,mocha和should.js的新手,我正在尝试为返回promise的异步方法编写测试。这是我的测试代码:

var should = require("should"),
    tideRetriever = require("../tide-retriever"),
    moment = require("moment"),
    timeFormat = "YYYY-MM-DD-HH:mm:ss",
    from = moment("2013-03-06T00:00:00", timeFormat),
    to = moment("2013-03-12T23:59:00", timeFormat),
    expectedCount = 300;

describe("tide retriever", function() {
    it("should retrieve and parse tide CSV data", function() {
        tideRetriever.get(from, to).then(
            function(entries) { // resolve
                entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount);
            },
            function(err) { // reject
                should.fail("Promise rejected", err);
            }
        );
    });
});

当我手动测试tideRetriever.get方法时,它会一致地解析一个包含27个元素的数组(如预期的那样),但无论expectedCount的值如何,测试都不会失败。这是我简单的手动测试:

tideRetriever.get(from, to).then(
    function(entries) {
        console.log(entries, entries.length);
    },
    function(err) {
        console.log("Promise rejected", err);
    }
);

如果有必要,我也可以发布正在测试的模块的源代码。

我是否误解了摩卡或者应该是什么?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:7)

更新

在某些时候,Mocha开始支持从测试中返回Promise而不是添加done()回调。原始答案仍然有效,但测试看起来更干净:

it("should retrieve and parse tide CSV data", function() {
    return tideRetriever.get(from, to).then(
        function(entries) {
            entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount);
        }
    );
});

查看this gist以获取完整示例。

ORIGINAL

<强>注意即可。接受的答案仅适用于普通的异步代码,而不适用于Promises(作者使用)。

区别在于Promise回调抛出的异常不能被应用程序捕获(在我们的例子中是Mocha),因此测试将因超时而不是实际断言而失败。根据Promise实现,可以记录或不记录断言。请参阅when documentation

,详细了解相关信息

要使用Promises正确处理此问题,您应该将err对象传递给done()回调而不是抛出它。您可以使用Promise.catch()方法(不在onRejection()的{​​{1}}回调中)执行此操作,因为它不会捕获同一方法的Promise.then()回调中的异常。见下面的例子:

onFulfilment()

PS describe("tide retriever", function() { it("should retrieve and parse tide CSV data", function(done) { tideRetriever.get(from, to).then( function(entries) { // resolve entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount); done(); // test passes }, function(err) { // reject done(err); // Promise rejected } ).catch(function (err) { done(err); // should throwed assertion }); }); }); 回调用于三个地方以涵盖所有可能的情况。但是,如果您不需要任何特殊逻辑,则可以完全删除done()回调。在这种情况下,onRejection()也会处理拒绝。

答案 1 :(得分:4)

在测试异步代码时,您需要在测试完成时告诉Mocha(无论是通过还是失败)。这是通过为测试函数指定一个参数来完成的,Mocha使用done函数填充该参数。所以你的代码可能如下所示:

describe("tide retriever", function() {
    it("should retrieve and parse tide CSV data", function(done) {
        tideRetriever.get(from, to).then(
            function(entries) { // resolve
                entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount);
                done();
            },
            function(err) { // reject
                should.fail("Promise rejected", err);
                done();
            }
        );
    });
});

请注意,Mocha知道这种情况的方式是异步测试,需要等到调用done()时才指定该参数。

此外,如果您的承诺有一个“已完成”的处理程序,它会在成功和失败时触发,您也可以在其中调用done(),从而保存一个电话。

更多信息: http://mochajs.github.io/mocha/#asynchronous-code