简体   繁体   English

使用TypeScript反应测试库:设置输入值

[英]React Testing Library with TypeScript: Set an input's value

I'm building a React application using TypeScript. 我正在使用TypeScript构建一个React应用程序。 I do my component tests using React Testing Library. 我使用React Testing Library进行组件测试。

Let's say you have simple form like this: 假设你有这样简单的形式:

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}

In this video Kent (the creator of the library) shows how you would test the forms input inputs. 此视频中, Kent(图书馆的创建者)展示了如何测试表格输入输入。 The tests would look like this: 测试看起来像这样:

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',
  })
})

The problem is that he did it with plain JavaScript. 问题是他用普通的JavaScript做到了。 When doing this with TypeScript the lines where he sets .value throw the following errors 使用TypeScript执行此操作时,他设置.value的行会引发以下错误

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

How would one test this functionality with TypeScript using React Testing Library? 如何使用React Testing Library使用TypeScript测试此功能? How would you set the input's values? 你会如何设置输入的值?

The typings provided by that library type the return value of getByLabelText as type: HTMLElement . 该库提供的类型将getByLabelText的返回值键入类型: HTMLElement Not all HTML elements have value properties, only things like HTMLInputElement do. 并非所有HTML元素都具有value属性,只有HTMLInputElement这样做。

The getByLabelText also has no sort of generic type through which you might be able to affect the output type, so essentially you will need to either unsafely cast the result to type HTMLInputElement or you will need to build a helper function that tells TypeScript whether or not the object is the right type: getByLabelText也没有通用类型,你可以通过它来影响输出类型,所以基本上你需要不安全地将结果转换为类型HTMLInputElement否则你需要构建一个帮助函数告诉TypeScript是否对象是正确的类型:

  1. Unsafe cast . 不安全的演员 All you really need to do is update any calls to getByLabelText where you expect it to be a type with a value property to: 你真正需要做的就是更新任何对getByLabelText调用,你希望它是一个带有value属性的类型:

     (getByLabelText(/username/i) as HTMLInputElement).value = 'chuck'; 
  2. Type validation . 类型验证 This method is a bit safer as you can provide a type validation function that will cause TypeScript to update the type: 此方法更安全,因为您可以提供类型验证函数,该函数将导致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... } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM