Test de réaction si l'entrée n'accepte qu'un nombre

Nov 22 2020

J'utilise la bibliothèque de test de réaction pour créer mon test.

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;

Mon 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('')
    })
});

Les tests sont maintenant réussis, mais pourquoi? Je viens de créer une entrée avec le type: nombre, pas de texte, donc je m'attends à ce que le test ne soit pas passé? Comment vérifier une entrée avec un numéro de type?

Réponses

3 ShuheiKagawa Nov 22 2020 at 07:44

C'est à cause de l'API Web. React fonctionne avec l'API Web sous le capot et react-testing-libraryexécute des tests à l'aide de l'API Web.

expect(h1).toHaveTextContent('123')vérifie la h1de » textContentla propriété, qui est un string.

C'est la même chose pour inputla valuepropriété de. HTMLInputElementLa valuepropriété de est toujours a string. Je ne sais pas à 100% pourquoi c'est comme ça, mais cela a du sens pour moi que ce HTMLInputElement.valuesoit toujours un stringpeu importe 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.
    };

Si vous voulez vraiment un number, HTMLInputElementa une autre propriété appelée valueAsNumber, qui est un nombre.

valueAsNumber

double: renvoie la valeur de l'élément, interprétée comme l'une des suivantes, dans l'ordre:

  • Une valeur de temps
  • Un numéro
  • NaN si la conversion est impossible

À propos, l'un des principes directeurs de la bibliothèque de tests est:

Il devrait être généralement utile pour tester les composants de l'application de la manière dont l'utilisateur l'utiliserait.

Les utilisateurs voient les nombres sur un écran sous forme de textes et ne se soucient pas de leur «type». Il est donc logique que nous écrivions des tests basés sur des textes que les utilisateurs voient. Par exemple, vous souhaiterez peut-être tester si un nombre est également bien formaté, comme à la 1,234,567place de 1234567, pour certaines applications.