Тестирование компонента входа с помощью Jest

#javascript #reactjs #jestjs #enzyme

#javascript #reactjs #jestjs #фермент

Вопрос:

Я не силен в тестировании и новичок в Jest и Enzyme. У меня есть компонент входа, который состоит из двух компонентов ввода текста для имени пользователя и пароля и компонента кнопки. Я тестирую каждый компонент по отдельности.

Я просто хотел бы проверить, что имя пользователя и пароль были возвращены onLogin.

Вот компонент:

 export const onLogin = (user, password) => {
  console.log('User', user, 'Password', password)
  return [user, password];
};

function Login() {
  const [user, setUser] = useState("");
  const [password, setPassword] = useState("");

  return (
    <LoginWrapper>
      <Branding brand={brand.brandName} />
      <FormWrapper onSubmit={(e) => { e.preventDefault(); onLogin(user, password) }}>
        <Stack>
          <TextInput
            className="username"
            type="text"
            label="Username"
            onChange={e => setUser(e.target.value)}
          />
        </Stack>
        <Stack>
          <TextInput
            className="password"
            type="password"
            label="Password"
            onChange={e => {setPassword(e.target.value); console.log('user', user)}}
          />
        </Stack>
        <Stack padding="0" align="right">
          <Button type="submit">Login</Button>
        </Stack>
      </FormWrapper>
    </LoginWrapper>
  );
}

export default Login;
  

Мой тест:

 describe("<Login />", () => {
  it("renders text input correctly", () => {
    const tree = renderer.create(<ThemeProvider theme={themes.default}><Login /></ThemeProvider>).toJSON();
    expect(tree).toMatchSnapshot();
  });

  it("calls onLogin when button clicked", () => {
    const onSubmitMock = jest.fn();

    const component = Enzyme.mount(
      <ThemeProvider theme={themes.default}><Login onSubmit={onSubmitMock} /></ThemeProvider>
    );

    component.find("input.username").simulate('change', { target: { value: 'myUser' } })
    component.find("input.password").simulate('change', { target: { value: 'myPassword' } })
    component.find("form").simulate("submit");

    console.log("onClickMock.mock", onSubmitMock.mock)
    expect(onSubmitMock).toBeCalled()
  });
});
  

Результаты:

Ожидалось, что была вызвана фиктивная функция, но она не была вызвана.

Комментарии:

1. Я предлагаю вам переместить onLogin функцию в другой файл, подобный login.utils.js . Вы можете использовать jest.mock('./login.utils') в своем тесте, так что import {onLogin} from './login.utils' это даст вам издевательскую функцию

Ответ №1:

Ваш подход к тестированию правильный, за исключением:

  1. В вашем тесте вы имитируете функцию обратного вызова и передаете ее как свойство onSubmit своему компоненту. Затем вам нужно вызвать эту функцию из вашего компонента при отправке формы.
  2. Вместо этого вы вызываете onLogin функцию вашего компонента, которая не имеет никаких последствий.

Чтобы исправить это, объявите свойства функции вашего компонента в качестве параметра и вызовите props.onSubmit в вашей форме отправки.

 function Login(props) {
    const [user, setUser] = useState("");
    const [password, setPassword] = useState("");

    return (
        <LoginWrapper>
            <Branding brand={brand.brandName} />
            <FormWrapper onSubmit={(e) => { e.preventDefault(); props.onSubmit(user, password) }}>
                <Stack>
                    <TextInput
                        className="username"
                        type="text"
                        label="Username"
                        onChange={(e) => setUser(e.target.value)}
                    />
                </Stack>
                <Stack>
                    <TextInput
                        className="password"
                        type="password"
                        label="Password"
                        onChange={(e) => { setPassword(e.target.value) }}
                    />
                </Stack>
                <Stack padding="0" align="right">
                    <Button type="submit">Login</Button>
                </Stack>
            </FormWrapper>
        </LoginWrapper>
    );
}