title: Testing React Functional Component with Hooks using Jest
body: <p>So I'm moving away from class based components to functional components but am stuck while writing test with jest/enzyme for the methods inside the functional components which explicitly uses hooks. Here is the stripped down version of my code.</p>
  
  <pre><code>function validateEmail(email: string): boolean {
    return email.includes('@');
  }
  
  const Login: React.FC&lt;IProps&gt; = (props) =&gt; {
    const [isLoginDisabled, setIsLoginDisabled] = React.useState&lt;boolean&gt;(true);
    const [email, setEmail] = React.useState&lt;string&gt;('');
    const [password, setPassword] = React.useState&lt;string&gt;('');
  
    React.useLayoutEffect(() =&gt; {
      validateForm();
    }, [email, password]);
  
    const validateForm = () =&gt; {
      setIsLoginDisabled(password.length &lt; 8 || !validateEmail(email));
    };
  
    const handleEmailChange = (evt: React.FormEvent&lt;HTMLFormElement&gt;) =&gt; {
      const emailValue = (evt.target as HTMLInputElement).value.trim();
      setEmail(emailValue);
    };
  
    const handlePasswordChange = (evt: React.FormEvent&lt;HTMLFormElement&gt;) =&gt; {
      const passwordValue = (evt.target as HTMLInputElement).value.trim();
      setPassword(passwordValue);
    };
  
    const handleSubmit = () =&gt; {
      setIsLoginDisabled(true);
        // ajax().then(() =&gt; { setIsLoginDisabled(false); });
    };
  
    const renderSigninForm = () =&gt; (
      &lt;&gt;
        &lt;form&gt;
          &lt;Email
            isValid={validateEmail(email)}
            onBlur={handleEmailChange}
          /&gt;
          &lt;Password
            onChange={handlePasswordChange}
          /&gt;
          &lt;Button onClick={handleSubmit} disabled={isLoginDisabled}&gt;Login&lt;/Button&gt;
        &lt;/form&gt;
      &lt;/&gt;
    );
  
    return (
    &lt;&gt;
      {renderSigninForm()}
    &lt;/&gt;);
  };
  
  export default Login;
  </code></pre>
  
  <p>I know I can write tests for <code>validateEmail</code> by exporting it. But what about testing the <code>validateForm</code> or <code>handleSubmit</code> methods. If it were a class based components I could just shallow the component and use it from the instance as</p>
  
  <pre class="lang-js prettyprint-override"><code>const wrapper = shallow(&lt;Login /&gt;);
  wrapper.instance().validateForm()
  </code></pre>
  
  <p>But this doesn't work with functional components as the internal methods can't be accessed this way. Is there any way to access these methods or should the functional components be treated as a blackbox while testing?</p>