1

我不是单元测试方面的专家,我试图在我的虚拟 todoapp 项目上实现 100% 的覆盖率,这对于像 TodoList 组件这样的简单组件来说很容易,但是 AddTodo 组件呢?

import React, {PropTypes} from 'react'
import {compose, withState, withProps} from 'recompose'

/**
* Form to create new todos.
*/

const enhance = compose(
  withState('value', 'setValue', ''),
  withProps(({value, setValue, addTodo}) => ({
    handleSubmit: e => (
      e.preventDefault(),
      addTodo(value),
      setValue('')
    ),
    handleChange: e => setValue(e.target.value),
  }))
)

const Component = ({value, handleSubmit, handleChange}) =>
  <form onSubmit={handleSubmit}>
    <input
      type="text"
      value={value}
      onChange={handleChange}
    />
    <input type="submit" value="add"/>
  </form>

Component.displayName = 'FormNewTodo'
Component.propTypes = {
  value: PropTypes.string.isRequired,
  handleSubmit: PropTypes.func.isRequired,
  handleChange: PropTypes.func.isRequired,
}

export default enhance(Component)

这是我当前的 AddTodo 测试:

import React from 'react'
import {shallow} from 'enzyme'
import FormNewTodo from './index'

test('it should render properly', () => {
  const wrapper = shallow(<FormNewTodo value="something"/>)

  expect(wrapper).toMatchSnapshot()
})

该测试产生以下覆盖率:Stmts 62.5、Branch 100、Funcs 25、Lines 62.5。

未覆盖的线路是:12、16、21。

我应该如何正确测试它们?我错过了什么?有一些关于该主题的资源吗?


我终于解决了我的问题,注意目标是实现 100% 的覆盖率,仅此而已。

这是我的解决方案:

import React from 'react'
import {shallow} from 'enzyme'
import FormNewTodo from './index'

test('<FormNewTodo/>', () => {
  const preventDefault = jest.fn()
  const addTodo = jest.fn()
  const subject = shallow(
    <FormNewTodo
      addTodo={addTodo}
    />
  )

  subject.dive()
    .find('[type="text"]')
    .simulate('change', {target: {value: 'woot'}})

  subject.dive()
    .simulate('submit', {preventDefault})

  expect(preventDefault).toHaveBeenCalled()
  expect(addTodo).toHaveBeenCalled()
})
4

2 回答 2

1

和函数没有被调用,所以覆盖率报告说这些行没有被覆盖handleSubmithandleChange

因为你已经有了enzyme,你可以用它来模拟触发这些处理程序的事件。

例如:

wrapper.find('input').simulate('click') // trigger handleChange
wrapper.find('form').simulate('submit') // trigger handleSubmit
于 2016-12-29T12:38:19.070 回答
0

我不熟悉 recompose 但我假设您未经测试的代码是onChangeandonSubmit回调函数,setValue并且addTodo是您的组件的道具。要对此进行测试,您需要将它们作为间谍(使用创建的jest.fn())传递给您的组件。然后你必须触发onChangeand onSubmit,并测试他们用正确的参数调用的间谍

test('it submits the form', () => {
  //create the spies for your callbacks
  const setValue = jest.fn()
  const addTodo = jest.fn()

  //pass them to your rendered component
  const wrapper = shallow(
    <FormNewTodo 
      value="something" 
      setValue={setValue} 
      addTodo={addTodo}
    />
  )
  //create a spy for your fake event
  const preventDefault = jest.fn()
  //trigger the submit by just calling the prop
  wrapper.trigger.prop('onSubmit')({preventDefault})
  //check that the functions are called with correct parameter
  expect(preventDefault).toHaveBeenCalled()
  expect(setValue).toHaveBeenCalledWith('')
  expect(addTodo).toHaveBeenCalledWith('something')

})
于 2016-12-20T22:08:23.700 回答