使用 useState() 钩子测试功能组件时设置状态
Set state when testing functional component with useState() hook
当我用酶测试 class 组件时,我可以 wrapper.setState({})
设置状态。当我用 useState()
钩子测试功能组件时,我现在怎么能做同样的事情?
例如在我的组件中我有:
const [mode, setMode] = useState("my value");
我想在测试中更改 mode
使用挂钩状态时,您的测试必须忽略状态等实现细节才能正确测试它。
您仍然可以确保组件将正确的状态传递给它的子组件。
您可以在 Kent C. Dodds 撰写的 blog post 中找到一个很好的例子。
这是其中的摘录和代码示例。
依赖于状态实现细节的测试 -
test('setOpenIndex sets the open index state properly', () => {
const wrapper = mount(<Accordion items={[]} />)
expect(wrapper.state('openIndex')).toBe(0)
wrapper.instance().setOpenIndex(1)
expect(wrapper.state('openIndex')).toBe(1)
})
不依赖状态实现细节的测试-
test('counter increments the count', () => {
const {container} = render(<Counter />)
const button = container.firstChild
expect(button.textContent).toBe('0')
fireEvent.click(button)
expect(button.textContent).toBe('1')
})
这是我找到的方法,我并不是说这是对还是错。在我的例子中,一段代码依赖于状态被设置为一个特定的值。我会保留我对 React 测试的看法。
在你的测试文件中:
调整你对反应库的导入
import * as React from 'react'
然后在你的测试中监视 useState 并模拟它的实现
const stateSetter = jest.fn()
jest
.spyOn(React, 'useState')
//Simulate that mode state value was set to 'new mode value'
.mockImplementation(stateValue => [stateValue='new mode value', stateSetter])
请注意,模拟 useState 这将适用于为您的测试调用 useState 的所有实例,因此如果您正在查看多个状态值,它们将全部设置为 'new mode value'.其他人也许可以帮助您解决这个问题。希望对你有帮助。
在测试文件的顶部,可以首先定义为:
import { useState } from 'react';
jest.mock('react', () => ({
...jest.requireActual('react'),
useState: jest.fn()
}));
const useStateMock: jest.Mock<typeof useState> = useState as never;
之后每次测试都可以使用不同的值来测试:
const setValue = jest.fn();
useStateMock
.mockImplementation(() => ['value', setValue]);
当我用酶测试 class 组件时,我可以 wrapper.setState({})
设置状态。当我用 useState()
钩子测试功能组件时,我现在怎么能做同样的事情?
例如在我的组件中我有:
const [mode, setMode] = useState("my value");
我想在测试中更改 mode
使用挂钩状态时,您的测试必须忽略状态等实现细节才能正确测试它。 您仍然可以确保组件将正确的状态传递给它的子组件。
您可以在 Kent C. Dodds 撰写的 blog post 中找到一个很好的例子。
这是其中的摘录和代码示例。
依赖于状态实现细节的测试 -
test('setOpenIndex sets the open index state properly', () => {
const wrapper = mount(<Accordion items={[]} />)
expect(wrapper.state('openIndex')).toBe(0)
wrapper.instance().setOpenIndex(1)
expect(wrapper.state('openIndex')).toBe(1)
})
不依赖状态实现细节的测试-
test('counter increments the count', () => {
const {container} = render(<Counter />)
const button = container.firstChild
expect(button.textContent).toBe('0')
fireEvent.click(button)
expect(button.textContent).toBe('1')
})
这是我找到的方法,我并不是说这是对还是错。在我的例子中,一段代码依赖于状态被设置为一个特定的值。我会保留我对 React 测试的看法。
在你的测试文件中: 调整你对反应库的导入
import * as React from 'react'
然后在你的测试中监视 useState 并模拟它的实现
const stateSetter = jest.fn()
jest
.spyOn(React, 'useState')
//Simulate that mode state value was set to 'new mode value'
.mockImplementation(stateValue => [stateValue='new mode value', stateSetter])
请注意,模拟 useState 这将适用于为您的测试调用 useState 的所有实例,因此如果您正在查看多个状态值,它们将全部设置为 'new mode value'.其他人也许可以帮助您解决这个问题。希望对你有帮助。
在测试文件的顶部,可以首先定义为:
import { useState } from 'react';
jest.mock('react', () => ({
...jest.requireActual('react'),
useState: jest.fn()
}));
const useStateMock: jest.Mock<typeof useState> = useState as never;
之后每次测试都可以使用不同的值来测试:
const setValue = jest.fn();
useStateMock
.mockImplementation(() => ['value', setValue]);