使用超级测试避免 Mocha 因断言错误而超时

Avoiding Mocha timeout on assertion error with SuperTest?

本文关键字:断言 错误 超时 Mocha 测试      更新时间:2023-09-26

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

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

我可以在尝试/最后包装断言,但这似乎有点令人讨厌:

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);
            }
          });
      });
  });
});

关于如何更好地处理这个问题的任何建议?也许柴HTTP可能会更好?

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

.end(function (err, res) {
    if (err) return done(err);
    // Any other response-related assertions here
    ...
    // Finish the test
    done();
});

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

// 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)保证测试将完成而不会出错。