柴的Expect.to.throw错误不相等

时间:2018-12-28 13:26:14

标签: javascript node.js chai

我试图断言(使用expect)引发了特定错误。

已成功捕获错误,但是错误比较失败。其中包括thrownCustomErrornew CustomError()以及thrownCustomErrorcustomErrorInstance。但是,似乎使用expect().to.throw(CustomError, 'Custom error')确实可以。

就我而言,我特别希望声明使用参数来产生错误消息的自定义错误,因此使用后者进行比较麻烦。

我在这里做错了什么?任何建议,不胜感激。

let chai = require("chai");
const expect = chai.expect;
const assert = chai.assert;

class CustomError extends Error{
    constructor() {
        super('Custom error')
    }
}

const throwFn = () => {
    throw new CustomError()
}

const customErrorInstance = new CustomError()

describe('CustomError Test', () => {
    it('should throw a CustomError (new)', () => {
        expect(throwFn).to.throw(new CustomError())
    })

    it('should throw a CustomError (const)', () => {
        expect(throwFn).to.throw(customErrorInstance)
    })

    it('should produce a strictly equal error', (done) => {
        try {
            throwFn()
        } catch (e) {
            assert(e === new CustomError(), 'Thrown error does not match new instance of error')
            assert(e === customErrorInstance, 'Throw error does not match const instance of error')
            done()
        }
        expect.fail()
    })
})

输出:

  CustomError Test
    1) should throw a CustomError (new)
    2) should throw a CustomError (const)
    3) should produce a strictly equal error


  0 passing (38ms)
  3 failing

  1) CustomError Test
       should throw a CustomError (new):

      AssertionError: expected [Function: throwFn] to throw 'Error: Custom error' but 'Error: Custom error' was thrown
      + expected - actual


      at Context.it (test.js:19:27)

  2) CustomError Test
       should throw a CustomError (const):

      AssertionError: expected [Function: throwFn] to throw 'Error: Custom error' but 'Error: Custom error' was thrown
      + expected - actual


      at Context.it (test.js:23:27)

  3) CustomError Test
       should produce a strictly equal error:
     AssertionError: Thrown error does not match new instance of error
      at Context.it (test.js:29:4)

2 个答案:

答案 0 :(得分:0)

您每次都在测试实例,因此您需要使throwFn抛出该实例:

const customErrorInstance = new CustomError()

const throwFn = () => {
    throw customErrorInstance
}

// should throw a CustomError (const)
expect(throwFn).to.throw(customErrorInstance);

第一次测试,您必须更改为该类,因为您要在函数中抛出一个单独的实例,然后尝试与期望中的新实例进行比较,所以这永远是不正确的,根据定义,实例不是严格等于另一个实例EVER:

const throwFn = () => {
    throw new CustomError()
}

expect(throwFn).to.throw(CustomError)

由于您正在尝试通过执行expect(throwFn).to.throw(new CustomError())比较实例,所以这永远不会成功。

这是您的代码被修改

let chai = require("chai");
const expect = chai.expect;
const assert = chai.assert;

class CustomError extends Error{
    constructor() {
        super('Custom error')
    }
}

const customErrorInstance = new CustomError()

const throwFn = () => {
    throw customErrorInstance;
}

describe('CustomError Test', () => {
    it('should throw a CustomError (new)', () => {
        expect(throwFn).to.throw(CustomError)
    })

    it('should throw a CustomError (const)', () => {
        expect(throwFn).to.throw(customErrorInstance)
    })

    it('should produce a strictly equal error', (done) => {
        try {
            throwFn()
        } catch (e) {
            assert(e !== new CustomError(), 'Thrown error instance is same as newly constructed! This is impossible!)
            assert(e === customErrorInstance, 'Throw error does not match const instance of error')
            done()
        }
        expect.fail()
    })
})

答案 1 :(得分:0)

在更深入地了解之后,蔡对错误相等的评估是……很奇怪。错误由消息和堆栈跟踪组成。由于根据错误的实例化位置,堆栈跟踪会有所不同,因此无法在expect.to.throw内实现相等性而不抛出相同的实例。

我找到的唯一可以断言错误消息的解决方案是这样的:

const a = new CustomError()
...
it('should produce a strictly equal error', (done) => {
    try {
        throwFn()
    } catch (e) {
        assert(e.message === a.message, 'Thrown error does not match new instance of error')
        done()
    }
    expect.fail()
})

(注意:在撰写本文时,有一个开放的PR可以删除/修改此行为https://github.com/chaijs/chai/pull/1220