我们如何在Jest

时间:2019-08-26 16:10:52

标签: javascript jestjs react-hooks

Im使用react钩子并将Use State用于组件状态。开玩笑地测试组件时,我看到我无法访问状态值并对其进行模拟。

有一堆代码正在状态中寻找不同的值。由于状态不可访问,因此我无法涵盖完整的代码覆盖范围。

请帮助我编写以下代码的测试用例。

const MyComponent = props => {
    const [counterSecond, setCounterSecond] = React.useState(8);
    const [counterFirst, setCounterFirst] = React.useState(0);

    const handleIncrement = () => {
        setCounterSecond(counterSecond + 1);
    };
    const handleDecrement = () => {
        setCounterSecond(counterSecond - 1);
    };

    React.useEffect(() => {
        if (counterSecond === 10) {
            setCounterSecond(0);
            setCounterFirst(1);
        }
        if (counterSecond === 3) {
            setCounterSecond(1);
            setCounterFirst(0);
        }
        if (counterSecond ===9) {
            setCounterSecond(2);
            setCounterFirst(1);
        }

    }, [counterSecond]);

    return (
        <div>
            <div onClick={handleIncrement} >Increment</div>
            <div onClick={handleDecrement} >Decrement</div>
        </div>
    );
};

export default MyComponent;

如您所见,该代码具有useEffect,它将监视counterSecond值的变化。但是只有当状态值匹配8或3或9时,才会覆盖内部条件。

您能否指导我编写Jest测试用例,以涵盖UserEffect的内部条件。

1)以及如何模拟任何状态值
2)如何在使用Hooks时检查Jest中的状态值

1 个答案:

答案 0 :(得分:0)

让我们假设您的组件呈现ILoggercounterFirst,否则它们的存在没有任何意义。像

counterSecond

然后,我们要测试我们的组件。我坚信我们不需要对状态或任何内部进行嘲弄或断言。相反,我们需要通过.... return ( <div> <span test-id="counter">{`${counterFirst}:${counterSecond}`}</span> <div onClick={handleIncrement} id="inc">Increment</div> <div onClick={handleDecrement} id="dec">Decrement</div> </div> ); 进行通信并检查render的结果,以检查组件的行为是否符合我们的预期。

因此,测试初始状态可能类似于:

props

但是如何处理function getCounter(wrapper) { return wrapper.find("['test-id'='counter']").text(); } it('renders 0:8 by default', () => { const wrapper = mount(<MyComponent />); expect(getCounter(wrapper)).toEqual('0:8'); }); 中的代码?如果您的酶版本最近,则应该可以使用。我相信。如果没有,请检查您使用的版本。

然后返回测试。取决于您的代码样本计数器,应该以稍微不典型的方式对递增和递减作出反应。对inc说:useEffect(因为0:8 -> 1:2 -> 1:0 -> 1:1 -> 1:2 -> 1:00:91:3中有适当的逻辑会导致重新渲染)。因此,我们将对其进行测试:

useEffect

实际上,这里的逻辑应该创建周期值(function doInc(wrapper) { wrapper.find("inc").props().onClick(); } it('jumps from 0:8 to 1:2 on inc', () => { const wrapper = mount(<MyComponent />); // 0:8 doInc(wrapper); expect(getCounter(wrapper)).toEqual('1:2'); }); ),因此我将在单个测试用例中对其进行测试。但是也许在您的真实组件中它不会循环。

您可能想知道如何为某些特定情况设置初始状态?同样的方法:通过调用1:2 -> 1:0 -> 1:1 -> 1:2 -> 1:0来模仿点击和其他通信。

props

也许做一些辅助功能是个好主意。

但是直接设置状态会更快吗?是的,会的。但这也会使测试不可靠。假设您的示例代码永远不会达到“ 0:9”。那可能是一个错误,而不是一个目标。我们希望测试可以帮助我们意识到这一点。通过直接设置状态,我们永远不会知道有问题。