【问题标题】:How to test a promise that connects to RabbitMQ?如何测试连接到 RabbitMQ 的 Promise?
【发布时间】:2018-12-15 00:31:10
【问题描述】:

您好,我正在使用 Chai 并尝试测试通过错误主机连接到 RabbitMQ 的自定义函数:

connect(host) {
    return new Promise((resolve, reject) => {
      amqp.connect(host)
        .then((conn) => {
          resolve(conn);
        })
        .catch((err) => {
          throw new Error(err);
        });
    });
  }

如果连接失败我会抛出一个错误,所以我会这样测试它:

it('shouldnt connect to RabbitMQ service successfully with the wrong host.', async () => {
      const result = await rabbitmqmailer.connect('amqp://wronghost');
      expect(result).to.equal(Error);
    });

连接失败并引发错误,但我的测试没有测试,只是我在终端上遇到了异常:

RabbitMQMailer component.
    RabbitMQMailer configuration information.
      ✓ should test rabbitmqmailer host configuration.
      ✓ should test rabbitmqmailer queue configuration.
      ✓ should get rabbitmqmailer empty emailContent value after make a new instance.
      ✓ should get rabbitmqmailer empty emailContentConsumed value after make a new instance.
      ✓ resolves
      ✓ should connect to RabbitMQ service successfully with the correct host. (60ms)
Unhandled rejection Error: Error: getaddrinfo EAI_AGAIN wronghost wronghost:5672
    at _amqplib2.default.connect.then.catch.err (/home/ubuntu/Desktop/easy-tracking/backend/src/components/rabbitmqmailer/rabbitmqmailer.dal.js:1:11069)
    at tryCatcher (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/promise.js:690:18)
    at _drainQueueStep (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/async.js:138:12)
    at _drainQueue (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/async.js:131:9)
    at Async._drainQueues (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/async.js:147:5)
    at Immediate.Async.drainQueues [as _onImmediate] (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/async.js:17:14)
    at processImmediate (timers.js:632:19)

      1) shouldnt connect to RabbitMQ service successfully with the wrong host.

我尝试在 trycatch 块上捕获异常,但这是同一个问题。

编辑:将测试更改为:

it('shouldnt connect to RabbitMQ service successfully with the wrong host.', async (done) => {
      const result = await rabbitmqmailer.connect('amqp://wronghost');
      expect(result).to.be.an.instanceof(Error);
      done();
    });


(node:18911) UnhandledPromiseRejectionWarning: Error: Error: getaddrinfo EAI_AGAIN wronghost wronghost:5672
    at _amqplib2.default.connect.then.catch.err (/home/ubuntu/Desktop/easy-tracking/backend/src/components/rabbitmqmailer/rabbitmqmailer.dal.js:1:11475)
    at tryCatcher (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/promise.js:690:18)
    at _drainQueueStep (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/async.js:138:12)
    at _drainQueue (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/async.js:131:9)
    at Async._drainQueues (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/async.js:147:5)
    at Immediate.Async.drainQueues (/home/ubuntu/Desktop/easy-tracking/backend/node_modules/amqplib/node_modules/bluebird/js/release/async.js:17:14)
    at processImmediate (timers.js:632:19)
(node:18911) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:18911) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
      1) shouldnt connect to RabbitMQ service successfully with the wrong host.


1) RabbitMQMailer component.
       RabbitMQMailer configuration information.
         shouldnt connect to RabbitMQ service successfully with the wrong host.:
     Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/home/ubuntu/Desktop/easy-tracking/backend/src/components/rabbitmqmailer/rabbitmqmailer.test.js)

【问题讨论】:

    标签: javascript unit-testing testing


    【解决方案1】:

    你没有正确地失败。你忘了reject。改为这样做:

    connect(host) {
        return new Promise((resolve, reject) => {
          amqp.connect(host)
            .then((conn) => {
              resolve(conn);
            })
            .catch((err) => {
              reject(new Error(err)); // Pass the error to reject
            });
        });
      }
    

    在您的测试中,使用instanceof 匹配返回的Error

    it('shouldnt connect to RabbitMQ service successfully with the wrong host.', async () => {
          const result = await rabbitmqmailer.connect('amqp://wronghost');
          expect(result).to.be.an.instanceof(Error);
        });
    

    我也不知道你用什么来测试,但如果是jest,那么这个link可能会帮助你正确地测试promise。

    编辑:实际上是 nvm。我看到你在用 Chai

    【讨论】:

    • 好的,这样更好,因为它没有向我显示红色文本的错误我认为我的测试现在正在捕捉它,但它没有通过测试.. 我期待Error 实例相等但为什么失败? PD:是的,我正在使用 Chai
    • 这也不起作用:(我添加了日志错误(编辑)
    • @maudev try chai-as-promised 允许您使用 chai 测试 Promise
    【解决方案2】:

    你需要reject承诺。

    connect(host) {
        return new Promise((resolve, reject) => {
          amqp.connect(host)
            .then((conn) => resolve(conn))
            .catch((err) => reject(new Error(err));
       });
    }
    

    还有测试

    it('shouldnt connect to RabbitMQ service successfully with the wrong host.', () => {
      return rabbitmqmailer.connect('amqp://wronghost')
        .then(() => { assert.fail('was not supposed to succeed'); })
        .catch((err) => { expect(err).to.be.an.instanceof(Error); })
    })
    

    【讨论】:

    • 谢谢,.catch((err) => reject(new Error(err)); 行解决了异常,但测试失败,我和你一样
    • 能否请您发布新的“失败”按摩?
    • @maudev 请查看我的编辑并重试。让我知道它是否有效。
    • @Heimer Barcos 好的,我试过了,但我收到了这个错误:1) RabbitMQMailer component. RabbitMQMailer configuration information. shouldnt connect to RabbitMQ service successfully with the wrong host.: Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both. at rabbitmqmailer.connect.then.catch.err (src/components/rabbitmqmailer/rabbitmqmailer.test.js:73:9)
    【解决方案3】:

    您通常希望您的测试被隔离。我建议模拟您的 amqp 对象并期望调用 connect 方法。

    在设计模拟之前尝试并理解真正的connect 方法很重要

    你可以使用像https://sinonjs.org/这样的模拟框架

    【讨论】:

      【解决方案4】:

      终于找到了测试的方法

      it('shouldnt connect to RabbitMQ service successfully with the wrong host.', (done) => {
            (async () => {
              try {
                await rabbitmqmailer.connect('amqp://wronghost');
              } catch (error) {
                chai.assert.typeOf(error, 'error');
              } finally {
                done();
              }
            })();
          });
      

      但是有一些奇怪的问题,例如,如果我将类型更改为“字符串”,它会告诉我:

      (node:26053) UnhandledPromiseRejectionWarning: AssertionError: expected [Error: Error: getaddrinfo EAI_AGAIN wronghost wronghost:5672] to be a string
      

      但是!测试成功:

       ✓ shouldnt connect to RabbitMQ service successfully with the wrong host.
      

      我不知道为什么会这样,但它仍然有效,谢谢你的帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-13
        • 2018-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-16
        相关资源
        最近更新 更多