使用SuperTest避免断言错误时的Mocha超时?

时间:2014-12-31 00:04:54

标签: javascript sails.js mocha chai supertest

我有一些Sails.js API测试(使用Mocha),它们使用SuperTest的.end()方法在响应上运行一些Chai断言。

我在断言后调用测试的done()回调,但如果抛出断言错误,则测试超时。

我可以在try / finally中包装断言,但这看起来有点icky:

var expect = require('chai').expect;
var request = require('supertest');

// ...

describe('should list all tasks that the user is authorized to view', function () {

  it('the admin user should be able to see all tasks', function (done) {
    var agent = request.agent(sails.hooks.http.app);
    agent
      .post('/login')
      .send(userFixtures.admin())
      .end(function (err, res) {
        agent
          .get('/api/tasks')
          .expect(200)
          .end(function (err, res) {
            try {
              var tasks = res.body;
              expect(err).to.not.exist;
              expect(tasks).to.be.an('array');
              expect(tasks).to.have.length.of(2);
            } finally {
              done(err);
            }
          });
      });
  });
});

有关如何更好地处理此事的任何建议?也许Chai HTTP可能更好?

2 个答案:

答案 0 :(得分:1)

根据Supertest's documentation,您需要检查是否存在err,如果存在,则将其传递给done函数。像这样

.end(function (err, res) {
    if (err) return done(err);

    // Any other response-related assertions here
    ...

    // Finish the test
    done();
});

答案 1 :(得分:1)

您可以从test中传递登录逻辑。

// auth.js
var request = require('supertest'),
    agent = request.agent;

exports.login = function(done) {
    var loggedInAgent = agent(sails.hooks.http.app);
    loggedInAgent
        .post('/login')
        .send(userFixtures.admin())
        .end(function (err, res) {
            loggedInAgent.saveCookies(res);
            done(loggedInAgent);
        });
};

然后在测试中使用它:

describe('should list all tasks that the user is authorized to view', function () {

    var admin;

    before(function(done) {
        // do not forget to require this auth module
        auth.login(function(loggedInAgent) {
            admin = loggedInAgent;
            done();
        });
    });

    it('the admin user should be able to see all tasks', function (done) {

        admin
            .get('/api/tasks')
            .expect(function(res) 
                var tasks = res.body;
                expect(tasks).to.be.an('array');
                expect(tasks).to.have.length.of(2);
            })
            .end(done);

    });

    it('should have HTTP status 200', function() {

        admin
            .get('/api/tasks')
            .expect(200, done);

    });

});

使用这种方法,您不应该为每个测试登录管理员(您可以在描述块中一次又一次地重复使用管理员),并且您的测试用例变得更具可读性。

您不应该通过这种方法获得超时,因为.end(done)保证您的测试将完成而不会出现错误。