为啥直接在构造函数中创建 ES6 类的实例时 Jest 的 toThrow 不起作用?

Posted

技术标签:

【中文标题】为啥直接在构造函数中创建 ES6 类的实例时 Jest 的 toThrow 不起作用?【英文标题】:Why Jest's toThrow won't work when create an instance of a ES6 class directly in the constructor?为什么直接在构造函数中创建 ES6 类的实例时 Jest 的 toThrow 不起作用? 【发布时间】:2018-03-24 06:12:09 【问题描述】:
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() 中创建一个函数。

这里发生了什么?

【问题讨论】:

【参考方案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 断言中也同样有效。

【讨论】:

以上是关于为啥直接在构造函数中创建 ES6 类的实例时 Jest 的 toThrow 不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

ES6 Class(类)

ES6 浅谈class继承机制

通过其他类构造函数在主方法中创建对象时访问对象属性

为啥我应该在构造函数而不是 ngOnInit 中创建我的 Angular2 响应式表单?

在c++中创建了类,但在创建新对象时,编译显示:不存在默认构造函数

c ++是不是可以在不基于其基类的派生类中创建构造函数?