【问题标题】:Why Jest's toThrow won't work when create an instance of a ES6 class directly in the constructor?为什么直接在构造函数中创建 ES6 类的实例时 Jest 的 toThrow 不起作用?
【发布时间】:2025-11-24 00:30:03
【问题描述】:
class TestObject {
  constructor(value) {
    if (value === null || value === undefined) {
      throw new Error('Expect a value!');
    }
  }
}

describe('test the constructor', () => {
  test('it works', () => {
    expect(() => {
      new TestObject();
    }).toThrow();
  });

  test('not work', () => {
    expect(new TestObject()).toThrow();
  });
});

这里有 2 个测试用例,一个有效,另一个无效。

not work 的失败消息如下:

● 测试构造函数 › 不工作

期待一个值!

 at new TestObject (tests/client/utils/aaa.test.js:4:11)
 at Object.<anonymous> (tests/client/utils/aaa.test.js:17:12)
     at Promise (<anonymous>)
     at <anonymous>
 at process._tickCallback (internal/process/next_tick.js:188:7)

为什么我需要在函数调用中包装该调用,当函数只返回一个普通值,甚至是一个承诺时,我们不需要包装,我们可以使用async/await 来检查expect()而不是在expect() 中创建一个函数。

这里发生了什么?

【问题讨论】:

    标签: javascript ecmascript-6 jestjs es6-class


    【解决方案1】:

    这里

    expect(new TestObject()).toThrow();
    

    首先评估new TestObject(),然后是expect(...),然后是...toThrow(),按照operator precedence。当new TestObject() 抛出时,其他任何事情都无所谓。

    这就是为什么toThrow 需要一个应该抛出的函数:

    expect(() => {
      new TestObject();
    }).toThrow();
    

    这样在被调用时可以在内部用try..catch包裹起来。

    它在 Jasmine toThrow 和 Chai to.throw 断言中也同样有效。

    【讨论】:

      最近更新 更多