【问题标题】:How do I get a meaningful test error when assertion is in a promise?当断言在承诺中时,如何获得有意义的测试错误?
【发布时间】:2016-06-08 02:21:01
【问题描述】:

当我需要检查 Promise 中的内容时,我很难在测试中获得有意义的失败。

这是因为大多数测试框架在断言失败时使用throw,但那些被then 的promise 吸收...

例如,在下面我希望 Mocha 告诉我 'hello' 不等于 'world'...

Promise.resolve(42).then(function() {
  "hello".should.equal("world") 
})

Complete fiddle here

有了 Mocha,我们可以正式兑现承诺,但这个 swallows completely the error 更糟......

注意:我使用的是mochaexpect.js(因为我想兼容IE8)

【问题讨论】:

    标签: javascript unit-testing promise mocha.js expect.js


    【解决方案1】:

    使用 Mocha,我们可以正式返回承诺,但这完全消除了错误,因此更糟......

    在您的小提琴中,您使用的是 2013 年 4 月的 Mocha 1.9,并且不支持从测试中返回承诺。如果我将您的小提琴升级到最新的 Mocha,它就可以正常工作。

    【讨论】:

    • 你可以返回一个 Promise 来测试分辨率。你不能在测试拒绝时只返回一个 Promise,因为如果你的代码中有错误导致 Promise 意外解决,你的测试将错误地通过。
    • 嗯,你在这里所说的相当于重复地说“如果你写错代码,它就不能正常工作”。
    • 如果您的代码编写不正确,仅返回 Promise可能会让您的测试错误地通过。当您测试拒绝时,您的 Promise 始终有机会在到达您的catch 中的断言之前解决。不管是不是重言式,这就是它的工作原理。
    • 我第一次理解你所说的。绝对没有必要加粗任何东西。如果您从无根据的假设开始,即解决方案将无法正确实施,因为这是您决定想象的,那么解决方案将不起作用。这是您可以针对 SO 上发布的所有答案提出的反对意见。
    • 哦,我明白你的意思了。是的,我故意试图在问题的实际范围之外对问题的作者进行教育。
    【解决方案2】:

    这与其说是一个答案,不如说是一个建议?在这里使用before 钩子会很有用。

    describe('my promise', () => {
    
      let result;
      let err;
    
      before(done => {
        someAsync()
          .then(res => result = res)
          .then(done)
          .catch(e => {
            err = e;
            done();
          });
      });
    
      it('should reject error', () => {
        err.should.not.be.undefined(); // I use chai so I'm not familiar with should-esque api
        assert.includes(err.stack, 'this particular method should throw')
      });
    
    });
    

    您还可以使用 sinon 制作同步模拟,然后使用您的断言库提供的任何 should.throw 功能。

    【讨论】:

      【解决方案3】:

      要测试失败的 Promise,请执行以下操作:

      it('gives unusable error message - async', function(done){
        // Set up something that will lead to a rejected promise.
        var test = Promise.reject(new Error('Should error'));
      
        test
          .then(function () {
            done('Expected promise to reject');
          })
          .catch(function (err) {
            assert.equal(err.message, 'Should error', 'should be the error I expect');
            done();
          })
          // Just in case we missed something.
          .catch(done);
      });
      

      【讨论】:

      • 你绝对不需要需要用摩卡来做这个。只需回报承诺。
      • 您不能只返回 Promise,因为如果您的代码意外解析,Mocha 会认为您的测试通过并且您得到误报。您可以将.then 留在上面,但我将其包含在内是为了演示在测试 Promise 拒绝时可能出现的问题。
      • 当然,如果从无根据的假设开始,即所有其他解决方案都无法正确实施,那么只有您的解决方案有效。
      • 这不是没有根据的。测试 Promise 拒绝并不像 assert.throws 那样简单。还有一些额外的问题。
      • 好的,抱歉。你在技术上是对的。他并没有试图陷入拒绝。他抛出示例错误的事实实际上让我认为他是。
      猜你喜欢
      • 1970-01-01
      • 2018-07-03
      • 2017-03-29
      • 2017-08-06
      • 2018-05-10
      • 2011-03-25
      • 1970-01-01
      • 2016-12-20
      • 2021-04-04
      相关资源
      最近更新 更多