Как проверить onChange в React? - PullRequest
0 голосов
/ 21 мая 2019

У меня есть компонент <Input />, и мне нужен тестовый метод-обработчик onChange, но метод имитации не работает, и когда я тестирую свойство change, это состояние не изменяется.

Ниже показано, как я использую компонент <Input />:

...
let formFields = formElementsArray.map(formElement => (
        <Input
            key={formElement.id}
            elementType={formElement.config.elementType}
            elementConfig={formElement.config.elementConfig}
            value={formElement.config.value}
            invalid={!formElement.config.valid}
            shouldValidate={formElement.config.validation}
            touched={formElement.config.touched}
            changed={(event) => inputChangeHandler(event, formElement.id)} />
    ))
...

Ниже это мой <Input /> компонент:

import React from 'react';

import styles from './Input.module.css';

const input = (props) => {
    let inputElement = null;
    const inputClasses = [styles.InputElement];

    if (props.invalid && props.shouldValidate && props.touched) {
        inputClasses.push(styles.Invalid);
    }

    switch (props.elementType) {
        case ('input'):
            inputElement = <input
                className={inputClasses.join(' ')}
                {...props.elementConfig}
                value={props.value}
                onChange={props.changed} />;
            break;
        case ('textarea'):
            inputElement = <textarea
                className={inputClasses.join(' ')}
                {...props.elementConfig}
                value={props.value}
                onChange={props.changed} />;
            break;
        case ('select'):
            inputElement = <select
                className={inputClasses.join(' ')}
                {...props.elementConfig}
                value={props.value}
                onChange={props.changed}>
                {props.elementConfig.options.map(option => (
                    <option
                        key={option.value}
                        value={option.value}>{option.displayValue}</option>
                ))}
            </select>;
            break;
        default:
            inputElement = <input
                className={inputClasses.join(' ')}
                {...props.elementConfig}
                value={props.value}
                onChange={props.changed} />;
    }

    return (
        <div className={styles.Input}>
            {props.label && <label className={styles.Label}>{props.label}</label>}
            {inputElement}
        </div>
    )
};

export default input;

Ниже показано, как я проверяю onChange:

import React from 'react';
import { Redirect } from 'react-router-dom';
import thunk from 'redux-thunk';

import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import configureStore from 'redux-mock-store';

import { Auth } from './Auth';
import Spinner from '../../components/UI/Spinner/Spinner';
import Button from '../../components/UI/Button/Button';
import Input from '../../components/UI/Input/Input';

configure({ adapter: new Adapter() });

const setup = () => {
    const props = {
        onAuth: jest.fn()
    }

    const enzymeWrapper = shallow(<Auth {...props} />);

    return {
        enzymeWrapper,
        props
    }
}

describe('<Auth />', () => {

    it('should create user when form is submitted', () => {
        const { enzymeWrapper: wrapper, props: reduxProps } = setup();
        const form = wrapper.find('form');
        const inputs = form.find(Input);
        const emailInput = inputs.at(0);
        const passwordInput = inputs.at(1);
        const email = "email@servidor.com";
        const password = "senha";

        // below the onChange doesn't works
        emailInput.simulate('change', {
            target: {
                value: email
            }
        });
        passwordInput.simulate('change', {
            target: {
                value: password
            }
        });
        // below the onChange doesn't works
        emailInput.find('input').simulate('change', {
            target: {
                value: email
            }
        });
        passwordInput.find('input').simulate('change', {
            target: {
                value: password
            }
        });
        // below the onChange works, but state doesn't change
        emailInput.props().changed({
            target: {
                value: email
            }
        }, 0);
        passwordInput.props().changed({
            target: {
                value: password
            }
        }, 1);

        expect(emailInput.props().value).toEqual(email);
        expect(passwordInput.props().value).toEqual(password);
    });
});

Мои рассуждения верны? Как проверить onChange?

1 Ответ

1 голос
/ 21 мая 2019

Вы находитесь в правильном направлении, просто пропустили пару вещей.

Во-первых, React Hooks может быть сложно протестировать, но вы на самом деле не используете хуки (по крайней мере, в коде, который вы опубликовали)так что не беспокойтесь об этом:)

Во-вторых, в вашем тесте отсутствует оператор expect.Когда вы тестируете, вы хотите проверить, работает ли что-то, и вы используете для этого expect.

Итак, после этого фрагмента кода:

emailInput.simulate('change', {
    target: {
        value: email
    }
});

У вас может быть что-то вроде:

expect(emailInput.value).toEqual(email);

Вы можете следовать примеру из документации фермента здесь .

Также вы можете проверить документацию expect здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...