title: Testing a login form with jest and the react-testing library
body: <p>I have this login form in react:</p>
  <pre><code>import React from 'react';
  import {
    Card,CardBody,Container,Form,FormGroup,Label,Input,Button,Col,Row,UncontrolledAlert
  } from 'reactstrap';
  import { AuthLogin, AuthContext } from '../API/auth';
  import { InputType } from 'reactstrap/es/Input';
  
  function useInput(type: InputType): [string, JSX.Element] {
      const [value, setValue] = React.useState(&quot;&quot;);
      const inputId = type === &quot;text&quot; ? &quot;username&quot; : &quot;password&quot;;
      const input = &lt;Input id={inputId} value={value} type={type} onChange={e =&gt; setValue(e.target.value)} /&gt;;
      return [value, input];
  }
  
  
  export default function Login() {
      const { state, dispatch } = React.useContext(AuthContext);
      const [username, usernameInput] = useInput(&quot;text&quot;);
      const [password, passwordInput] = useInput(&quot;password&quot;);
  
      const failureMessage = () =&gt; {
          if (state.login_error) {
              return (
                  &lt;UncontrolledAlert color=&quot;danger&quot;&gt;
                      Login failed: {state.login_error}
                  &lt;/UncontrolledAlert&gt;
              )
  
          }
      };
  
      const submitDisabled = () =&gt; username.length === 0 || password.length === 0;
  
      const handleSubmit = (e: React.FormEvent&lt;HTMLFormElement&gt;) =&gt; {
          const doLogin = async () =&gt; {
              await AuthLogin(dispatch, username, password);
          };
  
          e.preventDefault()
          doLogin();
      }
  
      return (
          &lt;div&gt;
              &lt;Container&gt;
                  &lt;Row&gt;
                      &lt;Col&gt;&lt;h1&gt;Login&lt;/h1&gt;&lt;/Col&gt;
                  &lt;/Row&gt;
                  {failureMessage()}
                  &lt;Card className=&quot;login&quot;&gt;
                      &lt;CardBody&gt;
                          &lt;Form onSubmit={handleSubmit}&gt;
                              &lt;FormGroup row&gt;
                                  &lt;Label for='username' sm={2}&gt;Username&lt;/Label&gt;
                                  &lt;Col sm={12}&gt;
                                      {usernameInput}
                                  &lt;/Col&gt;
                              &lt;/FormGroup&gt;
                              &lt;FormGroup row&gt;
                                  &lt;Label for='password' sm={2}&gt;Password&lt;/Label&gt;
                                  &lt;Col sm={12}&gt;
                                      {passwordInput}
                                  &lt;/Col&gt;
                              &lt;/FormGroup&gt;
                              &lt;Button type=&quot;submit&quot; disabled={submitDisabled()}&gt;Log in&lt;/Button&gt;
                          &lt;/Form&gt;
                      &lt;/CardBody&gt;
                  &lt;/Card&gt;
              &lt;/Container&gt;
          &lt;/div&gt;
      );
  }
  </code></pre>
  <p>And I want to test authentication in my frontend testing. Here is one (passing) test I've written:</p>
  <pre><code>test('submits username and password', async () =&gt; {
  
      // ARRANGE
      const username = &quot;myusername&quot;;
      const password = &quot;pass1234&quot;;
      const mockLogin = jest.fn();
  
      render(&lt;Login onSubmit={mockLogin(username, password)} /&gt;);
  
      const usernameInput = screen.getByRole('textbox', { name: /Username/i });
      userEvent.type(usernameInput, 'myusername');
      const passwordInput = screen.getByLabelText('Password');
      userEvent.type(passwordInput, 'pass1234');
      const loginButton = screen.getByRole('button', { name: /^Log in$/i });
      expect(loginButton).not.toBeDisabled();
  
      // ACT
      userEvent.click(loginButton);
  
      // ASSERT
      await expect(mockLogin).toHaveBeenCalled();
      await expect(mockLogin).toHaveBeenCalledTimes(1);
      await expect(mockLogin).toHaveBeenCalledWith(&quot;myusername&quot;, &quot;pass1234&quot;);
    });
  
  });
  </code></pre>
  <p>I'm new to react and these particular frontend testing frameworks, so my questions are more conceptual:</p>
  <ul>
  <li>should I be testing the actual authentication implementation (as well as mocking)? (given the middleware unit tests do that anyway)</li>
  <li>if so, how do I accomplish that - when I don't mock, I can't seem to get the form to submit (unless I'm misunderstanding the feedback - when I screen.debug(), I still see the login form, rather than the authenticated page or a login error).</li>
  <li>mocking in this case doesn't seem to prove much other than mocking is possible - I'm not sure I see the point, other than ensuring the expected elements are in the page and enabled/disabled when appropriate. Is that the point?</li>
  </ul>
  <p>Thanks for your help.</p>