我使用useState钩子编写了一个功能组件,该组件本身可以正常工作,但是在测试时遇到了麻烦。我不明白如何在组件中创建初始状态。我尝试了多种模拟useState的方法,但没有一种有效:
describe('<Component/>', () => {
beforeEach() = > {
jest.spyOn(Readt, 'useState').mockImplementation( () => React.useState(['test']));
//Also tried this:
//React['useState'] = jest.fn().mockImplementation( () => React.useState(['test']));
}
it('should match snapshot', () => {
expect(wrapper).toMatchSnapshot()
}
}
我也看过这篇文章,但无法为我工作
我还读到您不应该在单元测试中模拟出useState,但是如果您不模拟出它,那么如何为组件设置初始状态呢?
谢谢。
编辑:关于下面的答案:
传递道具不会改变我要测试的状态。
我有一个按钮,当单击(一个状态)时,将呈现一个输入框,当用户键入(另一种状态)并按确定按钮(又是另一种状态)时,该输入框将基于输入框中的内容创建一个按钮。
传递的道具有助于呈现按钮列表,但不能控制用户在输入框中键入的内容。我试图在输入框中设置一个状态,然后模拟单击“确定”按钮并进行测试。我不是要测试反应本机useState功能。我只是想使用已经具有“ wrapper.setState”的酶,但是如何使用useState呢?
理想情况下,我想设置我的组件,设置用户在输入框中键入的状态,然后测试以查看“确定”按钮是否按预期进行。在此之前无需模拟所有点击。
组件的状态是其内部的,这是理解React组件的重要部分。一旦“理解”了这一点,便可以理解,任何测试都不应尝试更改它。
但是,如何为组件设置初始状态?
您将值传递给组件内部的useState
钩子。然后,您的测试应该使用该初始状态来测试您的组件……它们应该像传递非测试代码一样,通过传递道具来对其进行更改。
事实上,即使你以某种方式可以改变你的初始状态(这是不可能的据我所知),你的测试代码应该什么也不做,非测试代码不(除了建立测试其环境模拟真实的),因为整个点制作测试是为了验证您的非测试代码是否有效。
同样,您永远都不想测试正在测试的任何东西的内部,无论它是React组件还是其他任何东西。
如果这样做,那么编写的每个测试都会在这些内部结构发生任何变化的瞬间中断,并且测试价值的巨大部分在于它们使您可以更轻松地进行重构(如果您不测试内部结构)。相反,您想使用测试工具来衡量组件的输出(即,组件生成的HTML)。
再说一遍,这甚至与React无关。对任何事物进行良好的软件测试都不会试图改变或评估它们的内部结构。相反,好的测试应集中在外部,因为这都是每个人都可以使用的所有非测试代码,并且从概念上讲,您要测试的所有内容都应该成为测试代码的“黑匣子”。
编辑:回应评论/问题
老实说,您所做的编辑并没有真正改变我的回答,只是它提醒我酶确实可以更改测试中的状态(我自己从未使用过它,我忘记了它的存在)。
但同样,只是因为事情可能并不意味着它是一个好主意,并再次,你要测试的外部的东西,你的测试(不只是反应的组分)。React组件的状态就像一个函数内部的变量:它在该函数/组件的内部,应该避免直接进行测试。
您要测试的是外部部分,并且(根据您的编辑)似乎不是props
...但是它仍然是外部的:DOM。
因此,我反而建议做的是(再次)非测试代码正在做的相同事情:“单击”按钮。酶通过其“模拟”方法(https://airbnb.io/enzyme/docs/api/ReactWrapper/simulate.html)使此操作非常容易。
如果仅模拟创建所需状态的按钮序列,则将仅测试外部(即,以与在生产环境中使用的方式相同的方式测试代码),但是将能够测试所需的任何情况。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句