如何在不失败测试的情况下获得Jest toThrow的覆盖范围

时间:2018-03-22 04:00:05

标签: testing jestjs code-coverage enzyme throw

让我们说我用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()错了吗?

3 个答案:

答案 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()
})

<强>更新

在意识到问题是在shallowmount内(在进入测试之前)引发错误之后,我将整个事情简化为:

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

因此,如果你有机会在安装时不抛出错误 - 你将能够测试它。