Реагируйте на библиотеку тестирования с помощью TypeScript: установите значение для ввода - PullRequest
0 голосов
/ 07 ноября 2018

Я создаю приложение React с использованием TypeScript. Я делаю свои тесты компонентов, используя React Testing Library.

Допустим, у вас есть такая простая форма:

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}

В это видео Кент (создатель библиотеки) показывает, как вы будете тестировать входные данные форм. Тесты будут выглядеть так:

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. Делая это с Напечатайте строки, в которых он устанавливает .value, выдают следующие ошибки

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

Как можно протестировать эту функциональность с TypeScript, используя React Testing Library? Как бы вы установили значения входа?

1 Ответ

0 голосов
/ 07 ноября 2018

Типы, предоставляемые этой библиотекой, возвращают значение getByLabelText как тип: HTMLElement.Не все элементы HTML имеют свойства value, только такие вещи, как HTMLInputElement do.

. getByLabelText также не имеет универсального типа, с помощью которого вы можете влиять на тип вывода, так что, по сути, вывам нужно будет либо небезопасно привести результат к типу HTMLInputElement, либо вам нужно будет создать вспомогательную функцию, которая сообщает TypeScript, является ли объект правильным типом:

  1. Небезопасное приведение .Все, что вам действительно нужно, это обновить любые вызовы на getByLabelText, где вы ожидаете, что это будет тип со свойством value:

    (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...
    }
    
...