如何测试toThrow异常?

How to test toThrow exception?

在我的模板组件中,我使用 @Watch 执行如下验证

  @Watch('name')
  validateName(newValue: string) {
    const isBlank = typeof newValue !== 'string' || newValue === '';
    console.log('AYE!', isBlank);
    if (isBlank) { throw new Error('name: required') };
  }

现在我想开玩笑地测试一下

it('throws error when name is not supplied', async () => {
    const { root } = await newSpecPage({ components: [MyComponent], html: '<my-component></my-component>' });

    expect(() => {
      root.name = '';
    }).toThrow(new Error('name: required'))  
  })

我得到的结果如下

expect(received).toThrow(expected)

Expected message: "name: required"

Received function did not throw

  47 |     expect(() => {
  48 |       root.name = '';
> 49 |     }).toThrow(new Error('name: required'))  
     |        ^
  50 |   })
  51 | });
  52 | 

console.log
  AYE! true

  at MyComponent.validateName (src/xxx/my-component.tsx:31:13)
      at Array.map (<anonymous>)

我想知道我应该如何捕获 validateName 抛出的错误?

我们可以通过如下所示的 try catch 块来代替使用 toThrow 来获得类似的结果。

Stencil 还提供了 waitForChanges 方法,允许我们更改属性的值并等待它生效

it('throws error when name is not supplied', async () => {
    try {
      const { root, waitForChanges } = await newSpecPage({ components: [MyComponent], html: `<my-component name="xxx"></my-component>` });
      root.name = '';
      await waitForChanges()
    } catch (e) {
      expect(e).toStrictEqual(Error('name: required'));
    }
  })

更改道具后,您将不得不使用异步 waitForChanges()。您可以通过调用它然后使用 rejects.toEqual(...) 来检查它是否抛出。此外,您还必须 return expect(...) 语句,否则您的测试将在异步代码完成之前通过(并且您会在控制台中获得 UnhandledPromiseRejectionWarning)。

it('throws error when name is not supplied', async () => {
  const { root, waitForChanges } = await newSpecPage({
    components: [MyComponent],
    html: '<my-component></my-component>'
  });

  root.name = '';

  return expect(waitForChanges()).rejects.toEqual(new Error('name: required'));
})