【问题标题】:Chai http - double callback issueChai http - 双重回调问题
【发布时间】:2017-07-03 06:35:24
【问题描述】:

我使用 chai-http 对我的 REST api 进行了正常的单元测试。它失败并出现以下错误

warn: double callback!
error: { SyntaxError: Unexpected token { in JSON at position 58
    at Object.parse (native)
    at IncomingMessage.<anonymous> (E:\projects\node_modules\chai-http\node_modules\superagent\lib\node\parsers\json.js:8:35)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickCallback (internal/process/next_tick.js:104:9)
  rawResponse: '{"books":[],"count":0,"page":1,"pages":0,"pageSize":10}{"books":[],"count":0,"page":1,"pages":0,"pageSize":10}',
  statusCode: 200,
  response: undefined }

如您所见,rawResponse 是重复的,因此测试失败。我调试了代码,控制器代码只被调用一次,输出正确。但是不明白为什么会出现这个错误。

下面是测试代码

// some code to mock mongoose with mockgoose
....
....

let server = require('../../../server');
let should = chai.should();
chai.use(chaiHttp);


describe.only('Books', () => {
  describe('/GET book', () => {
      it('it should GET all the books', (done) => {
        chai.request(server)
            .get('/api/books')
            .end((err, res) => {
                console.log(res);
                res.should.have.status(200);

              done();
            }).catch(function(err){
                console.error(err);
                done(err);
            });
      });
  });
});

【问题讨论】:

    标签: node.js mocha.js chai chai-http mockgoose


    【解决方案1】:

    您正在混合使用两种类型的异步处理:使用 .end/.catch 而不是 .then/.catch .end

    因为出现错误,.end()(带有第一个参数,err,设置)和.catch() 都被调用,导致done 回调被调用两次。

    这是一个使用 .then/.catch 的解决方案,结合 Mocha 的内置承诺支持(不使用 done):

    it('it should GET all the books', () => {
      return chai.request(server)
          .get("/api/books")
          .then(res => {
            console.log(res);
            res.should.have.status(200);
          })
          .catch(err => {
            console.error(err);
            throw err; // Re-throw the error if the test should fail when an error happens
          });
    });
    

    并使用.end

    it('it should GET all the books', done => {
    
      chai.request(server)
          .get("/api/books")
          .end((err, res) => {
            if (err) return done(err);
            console.log(res);
            res.should.have.status(200);
            done();
          });
    
    });
    

    【讨论】:

    • 是的,记住,有了 promises Mocha 不需要 catch 语句!
    • @jesusgn90 除非测试实际上期望抛出错误:D
    • Mocha 检测承诺拒绝本身
    • @jesusgn90 一些测试预期会抛出一个错误,在这种情况下你需要添加一个.catch
    • @RajatSoni which sn-p?
    猜你喜欢
    • 2014-10-31
    • 2010-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多