前言
测试除了可以让我们对线上代码更有信心,更重要的是
当需要重构代码时,有测试用例的代码才叫重构,没有测试用例的代码叫重写
所以,测试对于软件工程来说是非常重要的,本文讲讲react hook的测试
如果对React测试不熟悉的话可以参考我之前的React的测试 - 基本的HTML测试
一、 background
1.1 原始方法
测试hook,我们不妨写一个组件把hook包裹起来,比如测试useCounter,那么就写一个CounterTest的临时组件
const CounterTest = () => {
const {count, increment, decrement} = useCounter()
return (<div>
<div>Current count: {count}</div>
<button onClick={increment}>increment</button>
<button onClick={decrement}>decrement</button>
</div>)
}
1.2 测试
这样测试临时组件就可以了
test('exposes the count and increment/decrement functions', () => {
render(<CounterTest />)
const increment = screen.getByRole('button', {name: /increment/i})
const decrement = screen.getByRole('button', {name: /decrement/i})
const message = screen.getByText(/current count/i)
expect(message).toHaveTextContent('Current count: 0')
fireEvent.click(increment)
expect(message).toHaveTextContent('Current count: 1')
fireEvent.click(decrement)
expect(message).toHaveTextContent('Current count: 0')
})
二、改进
2.1 直接测试hook
上面的测试需要用户写组件,但是如果hook复杂,组件也是很难保证正确性,所以需要直接测试hook
2.2 fake component
我们不妨设计一个fake component
,调用hook赋值给外部先定义的result
let result
function TestComponent(props) {
result = useCustomHook(props)
return null
}
这样我们就可以通过调用result来测试hook了
test('test hooks', () => {
render(<TestComponent />)
expect(result.count).toBe(0)
act(() => result.increment())
expect(result.count).toBe(1)
act(()=>result.decrement())
expect(result.count).toBe(0)
})
三、使用Library
3.1 react-hooks
其实我们可以调用library,而不用写fake component
import {renderHook, act} from '@testing-library/react-hooks'
import useCounter from '../../components/use-counter'
test('the step can be changed', () => {
const {result, rerender} = renderHook(useCounter, {
initialProps: {step: 3},
})
expect(result.current.count).toBe(0)
act(() => result.current.increment())
expect(result.current.count).toBe(3)
rerender({step: 2})
act(() => result.current.decrement())
expect(result.current.count).toBe(1)
})
总结
本文讲了如果测试react hook,包括写测试组件调用hook,写fake component或者使用react-hooks的test library