Testing 如何在测试不失败的情况下获得Jest toThrow的覆盖率
假设我正在使用jest-coverage测试以下React组件: 覆盖率报告将显示新错误“无效”的行被发现。因为.not.toThrow似乎没有涵盖任何内容,我用酶创建了以下测试:Testing 如何在测试不失败的情况下获得Jest toThrow的覆盖率,testing,jestjs,code-coverage,enzyme,throw,Testing,Jestjs,Code Coverage,Enzyme,Throw,假设我正在使用jest-coverage测试以下React组件: 覆盖率报告将显示新错误“无效”的行被发现。因为.not.toThrow似乎没有涵盖任何内容,我用酶创建了以下测试: const wrapper = shallow( <MyComponent invalid /> ) it('should throw', () => { function fn() { if (wrapper.instance().props.invalid) { t
const wrapper = shallow(
<MyComponent invalid />
)
it('should throw', () => {
function fn() {
if (wrapper.instance().props.invalid) {
throw new Error('invalid')
}
}
expect(fn).toThrow()
})
线被遮住了!然而,测试本身失败了,遇到了声明异常——这意味着原始组件应该抛出错误吗
我用错了吗?galki,我认为问题是在构造组件时抛出了错误。而且它没有通过测试,这应该是正确的。 相反,如果您可以在其他地方提取道具检查功能,在安装过程中不会调用该功能,那么它将非常有效。例如,我将您的代码片段修改为
export default class MyComponent extends React.Component {
constructor(props) {
super(props)
}
componentWillReceiveProps(nextProps) {
if (nextProps.invalid) {
throw new Error('invalid')
}
}
render() {
return (
<div/>
)
}
}
及
所以,如果您有机会在安装时不抛出错误,您将能够测试它。galki,我认为问题在于您在构建组件时抛出错误。而且它没有通过测试,这应该是正确的。 相反,如果您可以在其他地方提取道具检查功能,在安装过程中不会调用该功能,那么它将非常有效。例如,我将您的代码片段修改为
export default class MyComponent extends React.Component {
constructor(props) {
super(props)
}
componentWillReceiveProps(nextProps) {
if (nextProps.invalid) {
throw new Error('invalid')
}
}
render() {
return (
<div/>
)
}
}
及
因此,如果您有机会在装载时不抛出错误,您将能够对其进行测试。显然,这是连接到的。我通过使用具有componentDidCatch方法的父React组件包装MyComponent,成功地通过了测试 这使得测试通过了,但为了影响覆盖率,我不得不将“浅”改为“装载”。测试结果如下所示:
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()
})
显然,这与我们的工作有关。我通过使用具有componentDidCatch方法的父React组件包装MyComponent,成功地通过了测试 这使得测试通过了,但为了影响覆盖率,我不得不将“浅”改为“装载”。测试结果如下所示:
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()
})
意识到这是一个古老的问题,但对于未来的观众,我想我应该扩展@galki的答案。您不必使用try/catch,只需将shallow/mount包装在匿名函数中,然后使用.tothrower即可:
这给了你更清晰的代码,同样的结果。意识到这是一个老问题,但对于未来的观众,我想我会扩展@galki的答案。您不必使用try/catch,只需将shallow/mount包装在匿名函数中,然后使用.tothrower即可:
这会使代码更简洁,结果也一样。这不是应该的吗fn。toThrow@AndreasKöberle这不应该是期待fn吗。toThrow@AndreasKöberle componentWillReceiveProps在本例中不被调用。我想测试组件的创建,而不是updatecomponentWillReceiveProps,在这种情况下不调用。我想在组件创建上进行测试,而不是在更新上进行测试。您保存了哪些内容,这是正确的。TothRow仅适用于纯函数,如果我们使用渲染器或浅层,则此测试不起作用。与其使用let并分配try/catch的结果,为什么不将浅层封装在匿名函数中并对其调用.TothRower?例如,expect=>shall.tothrowerr;哇,你救了我,没错。TothRow仅适用于纯函数,如果我们使用渲染器或浅层,则此测试不起作用。与其使用let并分配try/catch的结果,为什么不将浅层封装在匿名函数中并对其调用.TothRower?例如,expect=>shall.tothrowerr;这也适用于无状态:expect=>shallowTestComponent.tothroweror;这也适用于无状态:expect=>shallowTestComponent.tothroweror;
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)
})
const TestComponent = () => {
throw new Error('Test error');
}
describe('Test Component', () => {
it('Throws an error', () => {
expect(() => shallow(<TestComponent />)).toThrowError();
});
});