【问题标题】:REST API test with Mocha & Chai- Unhandled promise rejection使用 Mocha 和 Chai 进行 REST API 测试 - 未处理的承诺拒绝
【发布时间】:2019-08-27 17:06:13
【问题描述】:

我制作了一个非常简单的 RESTful API,允许用户添加、删除和更新有关霍格沃茨学生的信息。 Mongo 充当持久层。

url/students 的 GET 请求应该返回所有学生对象的列表。在为它编写测试时,我写了

expect(res).to.equal('student list');

这只是为了确保测试会失败而进行的初步检查,但实际上并非如此,而是我收到此错误:

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AssertionError: expected { Object (domain, _events, ...) } to equal 'student list'

所以它知道这两个值是不同的,但不是测试失败,而是抛出一个错误。 我在下面粘贴了完整的测试代码。

let chai = require('chai');
let chaiHttp = require('chai-http');
var MongoClient = require('mongodb').MongoClient;
chai.use(chaiHttp);
const expect = chai.expect;

describe('Students', async () => {
  describe('/GET students', () => {
    it('should GET all the students', async () => {
      chai.request('http://localhost:5000')
        .get('/students')
        .then(function (res) {
          try {
            expect(res).to.equal('hola');
          } catch (err) {
            throw err;
          }
        })
        .catch(err => {
          throw err; //this gets thrown
        })
    });
  });
});

如果你能告诉我正确使用 async await 来编写这些测试的语法,请也这样做。

【问题讨论】:

  • .catch() 然后(...)。注意: async 语句只有在使用 await 语句时才有意义
  • 那行不通,不过我会更新上面的代码。添加 .catch 后,它捕获了 AssertionError 但关键是为什么会有 AssertionError 呢?
  • console.log res,如果 res != "hola",则抛出 AssertionError
  • res 应该是一个对象,但是expect 应该没有通过测试,为什么会有错误呢?为什么测试没有失败?
  • 尝试一个示例 it('should be true', ()=>expect(false).to.equal(true)) ,如果它像您想要的那样工作而不是您的示例,那是因为承诺。也许你可以检查一下:stackoverflow.com/questions/55520801/…

标签: javascript node.js ecmascript-6 mocha.js chai


【解决方案1】:

测试通过并记录 "Unhandled promise rejection" 警告,因为错误是在 Promise 中引发的,这只会导致 Promise 拒绝。

由于Promise没有返回或者await-ed,测试成功完成...

...因为没有任何东西在等待或处理被拒绝的Promise,Node.js 会记录一个警告。

详情

测试中抛出的错误将导致测试失败:

it('will fail', function () {
  throw new Error('the error');
});

...但是一个被拒绝的Promise 如果没有被返回或者await-ed 将不会通过测试:

it('will pass with "Unhandled promise rejection."', function() {
  Promise.reject(new Error('the error'));
});

.catch returns a Promise 所以抛出一个.catch 会返回一个被拒绝的Promise,但如果那个Promise 没有被返回或者await-ed 那么测试也将通过:

it('will also pass with "Unhandled promise rejection."', function() {
  Promise.reject(new Error('the error')).catch(err => { throw err });
});

...但是如果返回被拒绝的Promiseawait-ed,那么测试将失败:

it('will fail', async function() {
  await Promise.reject(new Error('the error'));
});

如果你能告诉我正确使用 async await 来编写这些测试的语法,请也这样做。

对于您的测试,您可以将其简化为:

const chai = require('chai');
const expect = chai.expect;
const chaiHttp = require('chai-http');
chai.use(chaiHttp);

describe('Students', async function() {
  describe('/GET students', function() {
    it('should GET all the students', async function() {
      const res = await chai.request('http://localhost:5000').get('/students');
      expect(res).to.equal('hola');  // <= this will fail as expected
    });
  });
});

详情

来自chai-httpdoc

如果Promise 可用,request() 将成为支持 Promise 的库

...所以chai.request(...).get(...) 返回一个Promise

您可以简单地 await Promise 并且测试将等到 Promise 解决后再继续。

【讨论】:

  • 非常感谢!这非常有帮助。
猜你喜欢
  • 1970-01-01
  • 2015-10-28
  • 2015-06-04
  • 2017-07-16
  • 2018-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多