Reactjs Jest测试通过,但未捕获错误并记录到控制台
有没有一种方法可以测试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');
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
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';
}
}