【问题标题】:How to use enzyme and jest to detect change React state如何使用酶和笑话来检测变化的反应状态
【发布时间】:2021-06-24 08:44:26
【问题描述】:

我有一个简单的 React 组件,当用户单击按钮时,我想增加状态的内部值并在输入按钮中呈现。

组件有效,但我无法用酶编写测试,基本上内部值没有更新。

我认为它与 setState 异步有关,您知道如何修复我的测试吗?

import * as React from 'react'

type TestCounterProps = Readonly<{
  defaultValue: number
  onClick: (value: number) => void
}>

export const TestCounter = ({ defaultValue, onClick }: TestCounterProps) => {
  const [value, setValue] = React.useState(defaultValue)

  const handleIncrease = () => {
    setValue(value + 1)
    onClick(value)
  }

  return (
    <div>
      <input value={value} readOnly />
      <button onClick={handleIncrease}>Click to increase</button>
    </div>
  )
}

测试:

import * as React from 'react'
import { mount } from 'enzyme'
import { TestCounter } from './TestCounter'

describe('TestCounter', () => {
  it('should increase counter by 1 when user click button', () => {
    const cbClick = jest.fn()
    const container = mount(<TestCounter defaultValue={0} onClick={cbClick} />)
    const input = container.find('input')
    const button = container.find('button')
    button.simulate('click')
    container.update()

    expect(input.props().value).toBe(1) // issue here still 0 <<<
    expect(cbClick).toBeCalledWith(1)
  })
})

【问题讨论】:

    标签: javascript reactjs jestjs enzyme


    【解决方案1】:

    我有一个类似的示例/组件,我将在此处将其过去,以便作为示例有用:

    import * as React from 'react'
    
    type CounterProps = Readonly<{
      initialCount: number
      onClick: (count: number) => void
    }>
    
    export default function Counter({ initialCount, onClick }: CounterProps) {
      const [count, setCount] = React.useState(initialCount)
    
      const handleIncrement = () => {
        setCount((prevState) => {
          const newCount = prevState + 1
          onClick(newCount)
          return newCount
        })
      }
    
      const handleIncrementWithDelay = () => {
        setTimeout(() => {
          setCount((prevState) => {
            const newCount = prevState + 1
            onClick(newCount)
            return newCount
          })
        }, 2000)
      }
    
      return (
        <div>
          Current value: {count}
          <button onClick={handleIncrement}>Increment</button>
          <button onClick={handleIncrementWithDelay}>Increment with delay</button>
        </div>
      )
    }
    
    

    测试:

    import * as React from 'react'
    import { mount, ReactWrapper } from 'enzyme'
    import Counter from './Counter'
    import { act } from 'react-dom/test-utils'
    
    const COUNT_UPDATE_DELAY_MS = 2000
    
    const waitForComponentToPaint = async (wrapper: ReactWrapper) => {
      await act(async () => {
        await new Promise((resolve) => setTimeout(resolve, 0))
        wrapper.update()
      })
    }
    
    describe('Counter', () => {
      beforeAll(() => {
        jest.useFakeTimers()
      })
    
      afterAll(() => {
        jest.useRealTimers()
      })
    
      it('should display initial count', () => {
        const cbClick = jest.fn()
        const wrapper = mount(<Counter initialCount={5} onClick={cbClick} />)
    
        expect(wrapper.text()).toContain('Current value: 5')
        expect(cbClick).not.toBeCalled()
      })
    
      it('should increment after "Increment" button is clicked', () => {
        const cbClick = jest.fn()
        const wrapper = mount(<Counter initialCount={5} onClick={cbClick} />)
    
        wrapper.find('button').at(0).simulate('click')
    
        expect(wrapper.text()).toContain('Current value: 6')
        expect(cbClick).toHaveBeenCalledWith(6)
      })
    
      it('should increment with delay after "Increment with delay" button is clicked', () => {
        const cbClick = jest.fn()
        const wrapper = mount(<Counter initialCount={5} onClick={cbClick} />)
        waitForComponentToPaint(wrapper)
    
        wrapper.find('button').at(1).simulate('click')
    
        jest.advanceTimersByTime(COUNT_UPDATE_DELAY_MS + 1000)
    
        expect(wrapper.text()).toContain('Current value: 6')
        expect(cbClick).toHaveBeenCalledWith(6)
      })
    })
    
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-18
      • 1970-01-01
      • 2020-06-14
      • 2019-03-25
      • 2019-01-20
      • 2018-08-24
      • 2018-03-23
      • 2019-04-05
      相关资源
      最近更新 更多