MochaJS:如何在测试之间共享断言/“它('应该')”代码

时间:2016-01-10 06:24:10

标签: node.js unit-testing mocha

我有一些与Nodejs一起运行的mocha测试来测试Web服务器。

许多测试应该导致服务器返回错误,例如400 Bad Request。

目前,测试中包含以下代码的许多副本:

it('should respond with 400 (Bad Request)', function (){
    expect(httpResponse.statusCode).to.equal(httpstatus.BAD_REQUEST);
});

这是一个简化的伪代码示例:

describe('When passing bad JSON data', function(){
    var response
    before(function(done){
        callUrlToInsert(url, badJson, function(err, resp){
            response = resp
            done()
        }
    }
    it('should respond with 400 (Bad Request)', function (){
        expect(httpResponse.statusCode).to.equal(httpstatus.BAD_REQUEST)
    })
}

这让我很烦,因为作为程序员,我尽可能避免重复代码。

但是,将其置于函数中不起作用:

function verifyItReturnedBadRequest400(httpResponse)
{
    it('should respond with 400 (Bad Request)', function (){
        expect(httpResponse.statusCode).to.equal(httpstatus.BAD_REQUEST);
    });
}

因为对it()的调用不会立即测试断言;我的[有限]理解是it()将闭包添加到测试列表中。因此,在检查完成时,httpResponse变量已超出范围。 (我不明白为什么会这样,因为在这两种情况下都有一个调用它();为什么在一个案例中它在另一个函数调用级别内是否重要?我可能会遗漏一些关于Javascript范围。)

有没有一种常见的方法来避免所有这些重复的代码?或者每个人都在那里复制他们所有的断言代码?这是我第一次涉足Mocha,所以我可能错过了一些明显的东西。

此外,还有一些奖励积分用于解释为什么功能方法不起作用?

谢谢!

2 个答案:

答案 0 :(得分:3)

维基上有一篇关于此的文章。 https://github.com/mochajs/mocha/wiki/Shared-Behaviours

我猜你的测试中有一些错误。将it()置于包装函数中可以正常工作。这是一个小型工作演示。

'use strict';

const assert = require('assert');

const xEqualsOne = () => {
  it('should be equal 1', () => {
    assert.equal(this.x, 1);
  });
};

describe('async number', () => {
  this.x = 0;

  before(done => {
    this.x++
    setTimeout(done, 100);
  });

  xEqualsOne();
});

答案 1 :(得分:2)

我猜您的代码看起来像这样:

describe('When passing bad JSON data', function(){
    var response
    before(function(done){
        callUrlToInsert(url, badJson, function(err, resp){
            response = resp
            done()
        }
    }
    verifyItReturnedBadRequest400(httpResponse)
}

这样想:

  1. it()创建了一个测试。
  2. 所有对it的调用都发生之前实际运行任何测试(您必须在运行之前创建测试)
  3. 传递给`之前'在创建测试后运行,但之前运行。
  4. verifyItReturnedBadRequest400调用it来创建测试,但是您在任何测试运行之前都在传递httpResponse,因此before还没有运行无论是。
  5. 您可以继续使用这种模式,但是您需要将httpresponse放在容器中,以便您可以传递对它的引用:

    describe('When passing bad JSON data', function(){
        var data = {};
        before(function(done){
            callUrlToInsert(url, badJson, function(err, resp){
                data.response = resp
                done()
            }
        }
        verifyItReturnedBadRequest400(data)
    }
    

    然后您的verifyItReturnedBadRequest400变为:

    function verifyItReturnedBadRequest400(data) {
        it('should respond with 400 (Bad Request)', function (){
            expect(data.response.statusCode).to.equal(httpstatus.BAD_REQUEST);
        });
    }