【问题标题】:How to test controlled React components with cypress-react-unit-test如何使用 cypress-react-unit-test 测试受控的 React 组件
【发布时间】:2020-09-15 21:40:33
【问题描述】:

我正在努力了解如何在使用 cypress-react-unit-test 时更新反应组件的道具。

这里我有一个简单的受控输入组件。

interface MyInputProps {
    inputVal: string
    onInputChanged(val: string): void
}

export const MyInput = ({ inputVal, onInputChanged }: MyInputProps) => {
    return <input
        type='text'
        value={inputVal}
        onChange={e => onInputChanged(e.target.value)}
    />
}

然后我想通过给它一个初始值'' 来测试该组件,然后执行类似cy.get('input').type('a') 的操作。然后我希望onInputChanged 回调会被调用。

但这就是我卡住的地方。我如何处理更新后的值 ('a')?我不能在测试中使用钩子或状态,那么如何让我的组件使用更新的值重新渲染?执行mount(&lt;MyInput inputVal='' /&gt;),然后执行mount(&lt;MyInput inputVal='a' /&gt;) 似乎是错误的,因为那时我正在安装不同的组件,并且我没有测试该组件对道具更新的反应。

// MyInput.spec.tsx
describe('My Input', () => {
    it('updates when props change', () => {
        mount(<MyInput
            inputVal=''
            onInputChanged={(newVal) => {
                /* What do I do here? How do I update the props */
                return null
            }}
        />);
        
        /* Update props */
        /* Re-render somehow */
    })
})

【问题讨论】:

  • 也许使用一个局部变量来保存当前的inputVal,挂载一次,有cypress.type('a-new-value'),检查局部变量是否更新,最后再次挂载并检查输入的值。跨度>
  • 看一下re-render的例子,本质上是使用了一个包装器组件(所谓的mini web app)。但是在测试中安装两次以更简单的方式完成同样的事情。

标签: reactjs typescript cypress


【解决方案1】:

我认为问题不在于您的测试,而在于您的 MyInput 组件。
将您的状态设置为MyInput 或使用defaultValue 而不是value

export const MyInput = ({ inputVal, onInputChanged }: MyInputProps) => {
  return (
    <input
      type="text"
      defaultValue={inputVal}
      onChange={(e) => onInputChanged(e.target.value)}
    />
  );
};

如你所知,设置value={inputVal} 将使输入永远不会改变,只有当你改变inputVal 时才会改变。

【讨论】:

    猜你喜欢
    • 2019-09-08
    • 1970-01-01
    • 2020-06-21
    • 1970-01-01
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多