Jest测试通过但未捕获错误并记录到控制台

Dea*_*mes 9 reactjs jestjs

有没有办法在Jest中测试组件中的自定义错误,而不会在控制台中抛出Uncaught错误?

这里我有一个简单的按钮组件:

import React from 'react';

export default class Button extends React.Component {
    render() {

        if (!this.props.type) {
            throw new Error('Button requires a type prop');
        }

        return (
            <button className={`btn btn-${this.props.type}`}>Button</button>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

在不提供type属性的情况下使用组件时,我希望抛出自定义错误.我也有以下Jest测试:

import React from 'react';
import ReactDOM from 'react-dom';
import Button from './button';

it('throws an error if the type prop is not defined', () => {
    const buttonType = undefined;
    const container = document.createElement('div');

    expect(() => {
        ReactDOM.render(<Button type={buttonType} />, container);
    }).toThrow('Button requires a type prop');
});
Run Code Online (Sandbox Code Playgroud)

单元测试通过,但控制台产生的错误类似于:

console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
Error: Uncaught [Error: Button requires a type prop]

The above error occurred in the <Button> component:
in Button (at button.spec.js:20)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/docs/error-boundaries.html to learn more about error boundaries.
Run Code Online (Sandbox Code Playgroud)

通常在Jasmine中,.toThrow()匹配器会自动捕获错误,并且不会记录日志.

我已经阅读了有关错误边界的内容,但这些似乎是在应用程序级别,而不是在组件级别.

我错过了一种更适合测试的方法吗?

编辑:使用以下版本:

  • 反应:16.2.0
  • react-dom:16.2.0
  • 开玩笑:22.2.2

sti*_*tel 5

我从jsdom打印虚拟错误而不是抛出错误时遇到了与虚拟控制台类似的问题。据我所知,Jest或任何其他测试框架都无法阻止代码打印到控制台。

我已通过替换负责打印到控制台的侦听器来解决此问题。以下代码setupFiles在Jest配置中配置的文件中运行。

// There should be a single listener which simply prints to the 
// console. We will wrap that listener in our own listener.
const listeners = window._virtualConsole.listeners("jsdomError");
const originalListener = listeners && listeners[0];

window._virtualConsole.removeAllListeners("jsdomError");

window._virtualConsole.addListener("jsdomError", (error) => {
  if (error.type !== "not implemented" && originalListener) {
    originalListener(error);
  }
  // swallow
});
Run Code Online (Sandbox Code Playgroud)

如您所见,在我们的例子中,打印到控制台的错误(多次出现,这是副作用,而不是测试的主要目的)是“未实现”的错误。因此,这些代码只会吞噬这些类型的错误。

该解决方案不是理想的解决方案,但是它将使原木保持清洁。

PS:如果您想减少吞下“真实”错误的风险,则可以在before测试套件的方法中使用此技巧,并使用该after方法来重置原始行为。