让我们说我用jest --coverage
测试下面的React组件:
class MyComponent extends React.Component {
constructor(props) {
super(props)
if (props.invalid) {
throw new Error('invalid')
}
}
}
覆盖率报告会说明throw new Error('invalid')
行未被发现。由于.not.toThrow()
似乎无法覆盖任何内容,因此我使用酶创建了以下测试:
const wrapper = shallow(
<MyComponent invalid />
)
it('should throw', () => {
function fn() {
if (wrapper.instance().props.invalid) {
throw new Error('invalid')
}
}
expect(fn).toThrow()
})
并且线被覆盖!然而,测试本身失败了encountered a declaration exception
- 意味着原始组件抛出错误(应该如此)?
我使用toThrow()
错了吗?
答案 0 :(得分:5)
显然这与how React 16 handles errors有关。我设法通过使用具有MyComponent
方法的父React组件包装componentDidCatch
来获得测试。
这使测试通过但影响覆盖率,我不得不将shallow
更改为mount
。测试最终看起来像这样:
class ParentComponent extends React.Component {
componentDidCatch(error) {
// console.log(error)
}
render() {
return this.props.children
}
}
class MyComponent extends React.Component {
constructor(props) {
super(props)
if (props.invalid) {
throw new Error('invalid')
}
}
}
const wrapper = mount(
<ParentComponent>
<MyComponent invalid />
</ParentComponent>
)
it('should throw', () => {
function fn() {
if (wrapper.props().invalid) {
throw new Error('invalid test')
}
}
expect(fn).toThrow()
})
<强>更新强>
在意识到问题是在shallow
或mount
内(在进入测试之前)引发错误之后,我将整个事情简化为:
class MyComponent extends React.Component {
constructor(props) {
super(props)
if (props.invalid) {
throw new Error('invalid')
}
}
}
it('should throw', () => {
let error
try {
shallow(<MyComponent invalid />)
} catch (e) {
error = e
}
expect(error).toBeInstanceOf(Error)
})
答案 1 :(得分:3)
意识到这是一个古老的问题,但是对于将来的观众,我认为我会扩展@galki的答案。除了使用try / catch之外,您还可以将shallow
/ mount
包装在一个匿名函数中,然后使用.toThrowError()
代替:
const TestComponent = () => {
throw new Error('Test error');
}
describe('Test Component', () => {
it('Throws an error', () => {
expect(() => shallow(<TestComponent />)).toThrowError();
});
});
这为您提供了更简洁的代码,并且结果相同。
答案 2 :(得分:0)
galki,我认为问题是你在构建组件时抛出错误。它没有经过测试,因为它应该(你完全正确)。 相反,如果您可以在其他地方提取支撑检查功能,在安装期间不会调用它 - 它将完美地工作。例如,我将您的代码段修改为
const wrapper = shallow(
<MyComponent />
)
it('should throw', () => {
function fn() {
wrapper.setProps({invalid: true});
};
expect(fn).toThrow();
})
和
persistent topic
因此,如果你有机会在安装时不抛出错误 - 你将能够测试它。