所以我想我找到了另一种使用useContext()钩子测试组件的方法。我看过一些教程来测试一个值是否可以从父上下文提供者成功传递给子组件,但是没有关于子对象的教程可以更新上下文值。
我的解决方案是将根父组件与提供程序一起呈现,因为状态最终会在根父组件中更改,然后传递给提供程序,然后再将其传递给所有子组件。 (对吗?)
测试似乎在应该通过时通过,而在不应该通过时不通过。 有人可以解释为什么这是测试useContext()挂钩的好方法。
父级根组件
...
const App = () => {
const [state, setState] = useState("Some Text")
const changeText = () => {
setState("Some Other Text")
}
...
<h1> Basic Hook useContext</h1>
<Context.Provider value={{changeTextProp: changeText,
stateProp: state
}} >
<TestHookContext />
</Context.Provider>
)}
上下文对象
import React from 'react';
const Context = React.createContext()
export default Context
子组件
import React, { useContext } from 'react';
import Context from '../store/context';
const TestHookContext = () => {
const context = useContext(Context)
return (
<div>
<button onClick={context.changeTextProp}>
Change Text
</button>
<p>{context.stateProp}</p>
</div>
)
}
和测试
import React from 'react';
import ReactDOM from 'react-dom';
import TestHookContext from '../test_hook_context.js';
import {render, fireEvent, cleanup} from '@testing-library/react';
import App from '../../../App'
import Context from '../../store/context';
afterEach(cleanup)
it('Context is updated by child component', () => {
const { container, getByText } = render(<App>
<Context.Provider>
<TestHookContext />
</Context.Provider>
</App>);
console.log(container)
expect(getByText(/Some/i).textContent).toBe("Some Text")
fireEvent.click(getByText("Change Text"))
expect(getByText(/Some/i).textContent).toBe("Some Other Text")
})
答案 0 :(得分:0)
您的示例/代码停滞不前。 (不确定是否需要安装包装<App />
-您应该直接包装Context Provider)。
对您的问题:
测试似乎在应该通过时通过,而在不应该通过时不通过。有人可以解释为什么这是测试useContext()挂钩的好方法。
使用useContext()
时 是一种很好的测试方法,因为看起来您已经抽象了上下文,因此您的子(消费)组件及其测试都使用相同的上下文。我没有看到任何理由(当您在示例中使用时)使用相同的上下文提供程序来模拟或仿真上下文提供程序的工作。
React测试库文档point out:
您的测试与软件使用方式越相似,它们给您的信心就越大。
因此,以与设置组件相同的方式来设置测试即可实现该目标。如果您在一个应用程序中有多个测试需要将它们包装在同一个上下文中,那么this blog post提供了一种巧妙的解决方案来重用该逻辑。