【问题标题】:React Testing Library with TypeScript: Set an input's value使用 TypeScript 的反应测试库:设置输入的值
【发布时间】:2019-04-11 05:34:11
【问题描述】:

我正在使用 TypeScript 构建一个 React 应用程序。我使用 React 测试库进行组件测试。

假设你有这样的简单表格:

import React from 'react'

function Login({onSubmit}) {
  return (
    <div>
      <form
        onSubmit={e => {
          e.preventDefault()
          const {username, password} = e.target.elements
          onSubmit({
            username: username.value,
            password: password.value,
          })
        }}
      >
        <label htmlFor="username">Username</label>
        <input id="username" />
        <label htmlFor="password">Password</label>
        <input id="password" type="password" />
        <br />
        <button type="submit">Submit</button>
      </form>
    </div>
  )
}

export {Login}

this videoKent(库的创建者)中展示了您将如何测试表单输入输入。测试如下所示:

import React from 'react'
import {renderIntoDocument, cleanup} from 'react-testing-library'
import {Login} from '../login'

afterEach(cleanup)

test('calls onSubmit with username and password', () => {
  const handleSubmit = jest.fn()
  const {getByLabelText, getByText} = renderIntoDocument(
    <Login onSubmit={handleSubmit} />,
  )
  getByLabelText(/username/i).value = 'chuck'
  getByLabelText(/password/i).value = 'norris'
  getByText(/submit/i).click()
  expect(handleSubmit).toHaveBeenCalledTimes(1)
  expect(handleSubmit).toHaveBeenCalledWith({
    username: 'chuck',
    password: 'norris',
  })
})

问题在于他是用纯 JavaScript 做到的。当这样做时 TypeScript 他设置.value 的行会抛出以下错误

[ts] Property 'value' does not exist on type 'HTMLElement'.

如何使用 React 测试库使用 TypeScript 测试此功能?您将如何设置输入的值?

【问题讨论】:

    标签: reactjs typescript unit-testing htmlelements react-testing-library


    【解决方案1】:

    该库提供的类型将getByLabelText 的返回值键入为:HTMLElement。并不是所有的 HTML 元素都有 value 属性,只有像 HTMLInputElement 这样的东西有。

    getByLabelText 也没有任何泛型类型,您可以通过它影响输出类型,因此基本上您需要将结果不安全地转换为类型HTMLInputElement,或者您需要构建一个助手告诉 TypeScript 对象是否是正确类型的函数:

    1. 不安全的演员表。您真正需要做的就是将任何对 getByLabelText 的调用更新为:

      (getByLabelText(/username/i) as HTMLInputElement).value = 'chuck';
      
    2. 类型验证。这种方法更安全一些,因为您可以提供一个类型验证函数,该函数将导致 TypeScript 更新类型:

      function isElementInput<T extends HTMLElement>(element: T): T is HTMLInputElement {
          // Validate that element is actually an input
          return element instanceof HTMLInputElement;
      }
      
      // Update your attempted value sets:
      const elem = getByLabelText(/username/i);
      if (isElementInput(elem)) {
          elem.value = 'chuck';
      } else {
          // Handle failure here...
      }
      

    【讨论】:

    • 天才!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    相关资源
    最近更新 更多