Reaguj test, jeśli wejście akceptuje tylko liczbę

Nov 22 2020

Używam biblioteki React Testing do tworzenia mojego testu.

import React, {useState} from 'react';

const Input = () => {
    const [state, setState] = useState(0);

    const onChange = (e) => {
        setState(e.target.value)
    };

    return (
        <div>
            <h1>{state}</h1>
            <input placeholder='type' type="number" value={state} onChange={onChange}/>
        </div>
    );
};

export default Input;

Mój test:

import Input from "./Input";
import { render, fireEvent } from '@testing-library/react'


describe('test if render', ()=> {
    test('check render text', ()=> {
        const { getByPlaceholderText, getByRole } = render(<Input />);
        const input = getByPlaceholderText('type');
        const h1 = getByRole('heading', {level: 1});
        fireEvent.change(input, { target: { value: "123" } });
        expect(h1).toHaveTextContent('123')
    });
    test('check not render text', ()=> {
        const { getByPlaceholderText, getByRole } = render(<Input />);
        const input = getByPlaceholderText('type');
        const h1 = getByRole('heading', {level: 1});
        fireEvent.change(input, { target: { value: "" } });
        expect(h1).toHaveTextContent('')
    })
});

Testy są teraz zdane, ale dlaczego? Właśnie utworzyłem dane wejściowe typu: numer, a nie tekst, więc oczekuję, że test nie zostanie zaliczony? Jak sprawdzić dane wejściowe z numerem typu?

Odpowiedzi

3 ShuheiKagawa Nov 22 2020 at 07:44

To z powodu internetowego interfejsu API. React współpracuje z internetowym interfejsem API pod maską i react-testing-libraryuruchamia testy przy użyciu internetowego interfejsu API.

expect(h1).toHaveTextContent('123')Kontrole w h1„s textContentwłasności, co jest string.

To samo dla input„s valuenieruchomości. HTMLInputElement„s valuewłaściwość jest zawsze string. Nie jestem w 100% pewien, dlaczego tak jest, ale dla mnie ma to sens, że HTMLInputElement.valuezawsze jest to stringniezależne type.

    const onChange = (e) => {
        setState(e.target.value) // e.target.value is already a string. So, the state gets a string instead of a number here.
    };

Jeśli naprawdę chcesz number, HTMLInputElementma wywoływaną inną właściwość valueAsNumber, która jest liczbą.

valueAsNumber

double: Zwraca wartość elementu, interpretowaną jako jedną z poniższych, w kolejności:

  • Wartość czasu
  • Numer
  • NaN, jeśli konwersja jest niemożliwa

Nawiasem mówiąc, jedną z przewodnich zasad Biblioteki testowej jest:

Powinien być ogólnie przydatny do testowania komponentów aplikacji w sposób, w jaki użytkownik będzie z niej korzystał.

Użytkownicy widzą liczby na ekranie jako teksty i nie dbają o ich „typ”. Dlatego sensowne jest pisanie testów na podstawie tekstów, które widzą użytkownicy. Na przykład możesz chcieć sprawdzić, czy liczba jest również pięknie sformatowana, jak 1,234,567zamiast 1234567, w niektórych aplikacjach.