【问题标题】:How do I get the actual server error when running supertest in mocha?在 mocha 中运行 supertest 时如何获取实际的服务器错误?
【发布时间】:2016-01-09 22:04:51
【问题描述】:

我有这段代码使用 supertest 和 mocha:

import request from 'supertest';

//....

var newGame;
describe('Creating game', function() {
  beforeEach(function(done) {
    request(app)
      .post('/api/games')
      .send({
        owner: 'Mr. X',
      })
      .expect(201)
      .expect('Content-Type', /json/)
      .end((err, res) => {
        if (err) {
          return done(err);
        }
        newGame = res.body;
        done();
      });
  });    

  describe('the created game', function() {

    it('should name the specified owner', function() {
      newGame.owner.should.equal('Mr. X');
    });

   ...
  })
});

当服务器代码抛出一些异常(例如访问未定义对象的属性)时,我会得到这个堆栈跟踪

Error: expected 201 "Created", got 500 "Internal Server Error"
  at Test._assertStatus (D:\Codes\theApp\node_modules\supertest\lib\test.js:232:12)
  at Test._assertFunction (D:\Codes\theApp\node_modules\supertest\lib\test.js:247:11)
  at Test.assert (D:\Codes\theApp\node_modules\supertest\lib\test.js:148:18)
  at Server.assert (D:\Codes\theApp\node_modules\supertest\lib\test.js:127:12)
  at emitCloseNT (net.js:1521:8)

而不是实际的错误,例如“访问未定义的属性”。我怎样才能得到实际的错误?

【问题讨论】:

  • 好问题,似乎调用实际函数的普通旧单元测试可能更好地追踪崩溃?或者也许有超级测试和单元测试的组合:/
  • 您能否为我的答案不正确添加理由或将我的答案标记为正确。谢谢。

标签: node.js mocha.js supertest


【解决方案1】:

可能有很多方法可以解决这个问题,但我认为 mocha 或 supertest 无法访问导致 500 发生的实际错误。

你用什么来创建app?例如,如果是 Express,则可以在测试期间添加 error-handling middleware,这会导致将任何 500 诱导错误记录到控制台。

例如这样:

function logErrors (err, req, res, next) {
  console.error(err.stack)
  next(err)
}

const request = supertest(app.use(logErrors))

【讨论】:

    【解决方案2】:

    您可以让您的测试代码监听进程将引发的 uncaughtException 事件。只要 express 应用程序在与测试工具相同的进程中进行所有处理,进程中的任何未处理异常都将发送到进程 uncaughtException 事件处理程序。现在,这里可能会变得有点棘手。由于它是基于事件的,因此可以在任何时候触发未处理的异常。因此,如果您想更加明确并且只想处理来自被测系统的异常,则需要在运行被测系统代码之前/之后添加/删除侦听器。这是您更新的示例以侦听未处理的异常。

    import request from 'supertest';
    
    //....
    
    var newGame;
    describe('Creating game', function() {
      beforeEach(function(done) {
        var unhandledException = undefined;
        var unhandledExceptionCallback = function(err) {
            unhandledException = err;
        }
        process.on('uncaughtException', unhandledExceptionCallback);
        request(app)
          .post('/api/games')
          .send({
            owner: 'Mr. X',
          })
          .expect(201)
          .expect('Content-Type', /json/)
          .end((err, res) => {
            process.removeListener('uncaughtException', unhandledExceptionCallback);
            if (unhandledException !== undefined){
              return done(unhandledException);
            } else if (err) {
              return done(err);
            }
            newGame = res.body;
            done();
          });
      });    
    
      describe('the created game', function() {
    
        it('should name the specified owner', function() {
          newGame.owner.should.equal('Mr. X');
        });
    
       ...
      })
    });
    

    【讨论】:

      【解决方案3】:

      我认为这是一个 api 设计问题。 api 应该为客户端提供有用的错误信息,尤其是当客户端输入的差异导致服务器端错误时。

      您可以在您的端点中执行此操作,也可以在某些中间件中全局执行此操作。

      【讨论】:

        猜你喜欢
        • 2017-10-28
        • 2017-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-21
        • 2019-03-21
        • 1970-01-01
        • 2017-01-16
        相关资源
        最近更新 更多