我正在使用玩笑/伊斯坦布尔来跟踪代码覆盖率。我有以下组件:
// Menu.jsx
const myComponent = ({ initialState }) = {
const [state, setState] = useState(initialState);
const [menuContent, setMenuContent] = useState(undefined);
return (
<Menu>
{state.accordions.map(item, index) => (
<MenuPanel id={item.id}>
{item.details && typeof item.details === 'function'
? <item.details setContent={myContent => setMenuContent(myContent)} />
: undefined}
</MenuPanel>
)}
</Menu>
)
}
在我对Menu.jsx
的测试中,笑话覆盖率报告抱怨setMenuContent
未包含在我的测试中。我应该如何测试像这样的钩子?我以为不可能。我尝试测试setContent
道具是否存在于子组件上,但这无济于事。关于如何使它通过覆盖率报告的任何想法?我在测试中使用浅层渲染。
答案 0 :(得分:1)
您可以为该特定组件模拟useState,请尝试以下操作:
const stateMock = jest.fn();
jest.mock('react', () => {
const ActualReact = require.requireActual('react');
return {
...ActualReact,
useState: () => ['value', stateMock], // what you want to return when useContext get fired goes here
};
});
每次您的组件调用useState
时,您的stateMock
都会被解雇,案件也将得到赔偿
这只是您可以做什么的一个最小示例,但是您可以增强模拟功能以识别每个状态调用
如果要保留React状态的默认行为,可以在组件主体外部声明回调函数,在这种情况下,有关代码行如下:
<item.details setContent={myContent => setMenuContent(myContent)} />
因此,您可以将其从组件中取出并执行类似的操作,而不是使用此匿名函数始终可能导致内存泄漏:
const setContent = (setMenuContent) => (myContent) => setMenuContent(myContent)
const myComponent = ({ initialState }) = {
const [state, setState] = useState(initialState);
const [menuContent, setMenuContent] = useState(undefined);
return (
<Menu>
{state.accordions.map(item, index) => (
<MenuPanel id={item.id}>
{item.details && typeof item.details === 'function'
? <item.details setContent={setContent(setMenuContent)} />
: undefined}
</MenuPanel>
)}
</Menu>
)
}
现在您可以导出此函数并用文本覆盖它,这将允许您模拟setMenuContent
export const setContent = (setMenuContent) => (myContent) => setMenuContent(myContent)
您的最后一个选择是使用诸如酶或react-testing-lib之类的东西,在dom中找到此item.details
组件并触发点击操作