3

LoginForm の送信ハンドラを起動しようとしています。ただし、何らかの理由で、モック関数が呼び出される代わりに、コンポーネントの実際のハンドラーが起動されます (外部 API を呼び出します)。代わりにモック ハンドラーが確実に呼び出されるようにするにはどうすればよいですか?

対象となる 3 つのコンポーネントを以下に示します (プレゼンテーション、コンテナー、およびテスト スイート)。

LoginForm.js

import { Formik, Form, Field } from 'formik';
import { CustomInput } from '..';

const LoginForm = ({ initialValues, handleSubmit, validate }) => {
  return (
    <Formik
      initialValues={initialValues}
      validate={validate}
      onSubmit={handleSubmit}
    >
      {({ isSubmitting, handleSubmit }) => {
        return (
        <Form onSubmit={handleSubmit}>
          <div className="d-flex flex-column justify-content-center align-items-center">
            <Field
              data-testid="usernameOrEmail"
              type="text"
              name="identifier"
              placeholder="Username/Email"
              component={CustomInput}
              inputClass="mb-4 mt-2 text-monospace"
            />
            <Field
              data-testid="login-password"
              type="password"
              name="password"
              placeholder="Password"
              component={CustomInput}
              inputClass="mb-4 mt-4 text-monospace"
            />
            <button
              data-testid="login-button"
              className="btn btn-primary btn-lg mt-3 text-monospace"
              type="submit"
              disabled={isSubmitting}
              style={{ textTransform: 'uppercase', minWidth: '12rem' }}
            >
              Submit
            </button>
          </div>
        </Form>
      )}}
    </Formik>
  );
};

export default LoginForm;

LoginPage.js

import React, { useContext } from 'react';
import { loginUser } from '../../services';
import { userContext } from '../../contexts';
import { loginValidator } from '../../helpers';
import { setAuthorizationToken, renderAlert } from '../../utils';
import LoginForm from './login-form';

const INITIAL_VALUES = { identifier: '', password: '' };

const LoginPage = props => {
  const { handleUserData, handleAuthStatus } = useContext(userContext);

  const handleSubmit = async (values, { setSubmitting }) => {
    try {
      const result = await loginUser(values);
      handleAuthStatus(true);
      handleUserData(result.data);
      setAuthorizationToken(result.data.token);
      props.history.push('/habits');
      renderAlert('success', 'Login Successful');
    } catch (err) {
      renderAlert('error', err.message);
    }
    setSubmitting(false);
  };

  return (
    <LoginForm
      initialValues={INITIAL_VALUES}
      validate={values => loginValidator(values)}
      handleSubmit={handleSubmit}
    />
  );
};

export default LoginPage;

LoginPage.spec.js

import React from 'react';
import { cleanup, getByTestId, fireEvent, wait } from 'react-testing-library';
import { renderWithRouter } from '../../../helpers';
import LoginPage from '../login-page';

afterEach(cleanup);
const handleSubmit = jest.fn();

test('<LoginPage /> renders with blank fields', () => {
  const { container } = renderWithRouter(<LoginPage />);

  const usernameOrEmailNode = getByTestId(container, 'usernameOrEmail');
  const passwordNode = getByTestId(container, 'login-password');
  const submitButtonNode = getByTestId(container, 'login-button');

  expect(usernameOrEmailNode.tagName).toBe('INPUT');
  expect(passwordNode.tagName).toBe('INPUT');
  expect(submitButtonNode.tagName).toBe('BUTTON');
  expect(usernameOrEmailNode.getAttribute('value')).toBe('');
  expect(passwordNode.getAttribute('value')).toBe('');
});

test('Clicking the submit button after entering values', async () => {
  const { container } = renderWithRouter(<LoginPage handleSubmit={handleSubmit} />);

  const usernameOrEmailNode = getByTestId(container, 'usernameOrEmail');
  const passwordNode = getByTestId(container, 'login-password');
  const submitButtonNode = getByTestId(container, 'login-button');

  fireEvent.change(usernameOrEmailNode, { target: { value: fakeUser.username }});
  fireEvent.change(passwordNode, { target: { value: fakeUser.password }});
  fireEvent.click(submitButtonNode);

  await wait(() => {
    expect(handleSubmit).toHaveBeenCalledTimes(1);
  });


  expect(usernameOrEmailNode.tagName).toBe('INPUT');
  expect(passwordNode.tagName).toBe('INPUT');
  expect(submitButtonNode.tagName).toBe('BUTTON');
  expect(usernameOrEmailNode.getAttribute('value')).toBe('');
  expect(passwordNode.getAttribute('value')).toBe('');
});```

4

1 に答える 1