测试组件使用自定义的钩子react-testing-library

时间:2020-02-17 10:15:24

标签: javascript reactjs react-testing-library

我正在使用react-testing-library通过自定义钩子测试我的组件。但是我无法通过。这是我的代码

function useInput<T>(): Return<T> {
    const [input, setInput] = useState<T>({} as T);
    const [isDirty, setDirty] = useState({} as Record<keyof T, boolean>);

    const handleInputChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
        setInput({
            ...input,
            [e.target.name]: e.target.value
        });
        setDirty({
            ...isDirty,
            [e.target.name]: true
        });
    };

    const resetInput = () => {
        Object.keys(input).map((v) => (input[v as keyof T] as unknown as string) = '');
        Object.keys(isDirty).map((v) => (isDirty[v as keyof T] as unknown as string) = '');
        setInput({...input});
        setDirty({...isDirty});
    };

    return [input, handleInputChange, isDirty, resetInput, setInput]
}

const Login: React.FC = () => {
    const [input, handleChangeInput, isDirty, resetInput] = useInput<IInput>();

    return (
                <input
                    value={input.username}
                    onChange={handleChangeInput}
                    name={'username'}
                    className={classNames(`shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline`)}
                    id={'username'} type={'text'} placeholder={'Username'}/>

    )
}

测试

import React from "react";
import {render, unmountComponentAtNode} from "react-dom";
import Login from './index'
import {renderHook, act as actHook} from '@testing-library/react-hooks'
import {MemoryRouter} from "react-router-dom";
import {useInput} from '../hooks';
import { fireEvent } from '@testing-library/react';


describe('test login', () => {
  it('to match snapshot', () => {
    render(
      <MemoryRouter>
        <Login/>
      </MemoryRouter>
      ,
      container);
    expect(container).toMatchSnapshot()
  });

  it('input correct when change username',  () => { //can't pass
     render(
      <MemoryRouter>
        <Login/>
      </MemoryRouter>
      ,
      container);

    const {result} = renderHook(() => useInput());
    const [input, handleChangeInput] = result.current;
    const inputName = container.querySelector('#username');
    fireEvent.change(inputName, {target: {value: 'test'}});

    actHook(() => {
      handleChangeInput({target: {name: 'username', value: 'test'}});
    });
    expect(input).toBe({
      username: 'test'
    })

  })
});

我的脚本测试是。当输入fireEvent调用时,输入更改值和钩子useInput中的值具有相同的值。但是我可以通过。我哪里错了?请帮忙

1 个答案:

答案 0 :(得分:1)

创建了反应挂钩测试库来测试挂钩而无需,而不必将其安装在测试组件上。您必须决定要么测试钩子本身(不使用Login组件),要么对整个组件进行测试-那么您根本不需要钩子测试库-react-testing-library应该足够了。您的 fireEvent 实际上“触发”了您的钩子,而没有下面的部分

const {result} = renderHook(() => useInput());
const [input, handleChangeInput] = result.current;