Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs Jest测试通过,但未捕获错误并记录到控制台_Reactjs_Jestjs - Fatal编程技术网

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

Reactjs Jest测试通过,但未捕获错误并记录到控制台,reactjs,jestjs,Reactjs,Jestjs,有没有一种方法可以测试Jest组件中的自定义错误,而不会在控制台中抛出未捕获的错误 这里我有一个简单的按钮组件: import React from 'react'; export default class Button extends React.Component { render() { if (!this.props.type) { throw new Error('Button requires a type prop');

有没有一种方法可以测试Jest组件中的自定义错误,而不会在控制台中抛出未捕获的错误

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

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>
        );
    }
}
从“React”导入React;
导出默认类按钮扩展React.Component{
render(){
如果(!this.props.type){
抛出新错误('按钮需要类型属性');
}
返回(
按钮
);
}
}
如果使用组件时没有提供type属性,我希望抛出自定义错误。我还有以下笑话测试:

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');
});
从“React”导入React;
从“react dom”导入react dom;
从“./按钮”导入按钮;
它('如果未定义类型属性,则引发错误',()=>{
const buttonType=未定义;
const container=document.createElement('div');
期望(()=>{
render(,容器);
}).toThrow(“按钮需要类型道具”);
});
单元测试通过,但是控制台会产生类似以下的错误:

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.
console.error节点_modules/jsdom/lib/jsdom/virtual console.js:29
错误:未捕获[错误:按钮需要类型属性]
组件中发生了上述错误:
in按钮(位于Button.spec.js:20)
考虑将错误边界添加到树中以自定义错误处理行为。
参观https://reactjs.org/docs/error-boundaries.html 了解有关错误边界的更多信息。
通常在Jasmine中,.toThrow()匹配器会自动捕获错误,并且不会记录日志

我读过关于错误边界的文章,但这些似乎是在应用程序级别,而不是组件级别

我是否错过了一种更适合测试这一点的方法

编辑:使用以下版本:

  • 反应:16.2.0
  • react-dom:16.2.0
  • 笑话:22.2.2

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

我已经通过替换负责打印到控制台的侦听器修复了这个问题。以下代码在Jest配置的
setupFiles
中配置的文件中运行

// 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
});
如您所见,在我们的例子中,打印到控制台的错误(多次,因为这是一个副作用,而不是我们测试的主要目的)是一个“未实现”错误。因此,这段代码只能接受这些类型的错误

此解决方案并不理想,但它可以保持日志更干净


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

问题确实在于React的错误处理防止错误冒泡到顶层,茉莉花能发现的地方。两种可能的解决办法:

Monkeypatch控制台。实际抛出的错误 这显然是一种黑客行为,如果React更改为使用不同的错误报告方法,它将被破坏。stijndepestel的答案是一种更稳健的方法

仅为测试创建错误边界
然后,您可以将您的测试包装在这样一个处理程序中,然后断言
errorInfo
不为空,并且它包含一个错误,正如您所期望的那样

解决方案对您有效吗?我两者都试过了。没有成功。
console.error = msg => { throw new Error(msg); };
let errorInfo = null;
class ErrorBoundary extends React.PureComponent {
    state = {hasError: false};

    componentDidCatch(err, info) {
        errorInfo = [err, info]
        this.setState({hasError: true});
    }

    render() {
        if (!this.state.hasError)
            return React.Children.only(this.props.children);
        return 'Errored';
    }
}