Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test form submit with jest and enzyme in react?

Tags:

I am learning reactjs form with hooks, now I would like to test form on submit using jest and enzyme.

here is my login component.

import React from 'react'

function Login() {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');

    const handleSubmit = async (e) => {
        e.preventDefault();
        // ....api calLS
    }
    return (
        <div>
             <form onSubmit={handleSubmit} className="login">
    
            <input type="email" id="email-input" name="email" value={email} onChange={e => setEmail(e.target.value)} />
        
            <input type="password" id="password-input" name="password" value={password} onChange={e =>setPassword(e.target.value)} />
            
            <input type="submit" value="Submit" />
             </form> 
        </div>
    )
}

export default Login

Here is the login.test.js file

 describe('my sweet test', () => {
    it('clicks it', () => {
      
       const wrapper = shallow(<Login />);
       const updatedEmailInput = simulateChangeOnInput(wrapper, 'input#email-input', '[email protected]')
       const updatedPasswordInput = simulateChangeOnInput(wrapper, 'input#password-input', 'death'); 

       expect(updatedEmailInput.props().value).toEqual('[email protected]');
       expect(updatedPasswordInput.props().value).toEqual('death');

       const instance = wrapper.instance()
       const spy = jest.spyOn(instance, 'handleSubmit')
   
       instance.forceUpdate();    
   
       const submitBtn = app.find('#sign-in')
       submitBtn.simulate('click')
       expect(spy).toHaveBeenCalled()

    })
    
  })

Unfortunately when I run npm test I get the following error. enter image description here

What do I need to do to solve this error or can someone provide a tutorial on how to test a form submit?

like image 984
The Dead Man Avatar asked Nov 14 '20 22:11

The Dead Man


People also ask

How do you test for Jest and enzymes?

Both Jest and Enzyme are meant to test the react applications. Jest can be used with any other Javascript framework, but Enzyme is meant to run on react only. Jest can be used without Enzyme, and snapshots can be created and tested perfectly fine. But the Enzyme adds additional functionality to it.


1 Answers

In the documentation it's said that you cant use shallow.instance() for functional components It will return null: https://enzymejs.github.io/enzyme/docs/api/ShallowWrapper/instance.html There was also a previous answer on this topik Enzyme instance() returns null

You can pass validated function handleSubmit to Login as a prop like there How to use jest.spyOn with React function component using Typescript

 // Unit test
  describe('SomeComponent' () => {
  it('validates model on button click', () => {
      const handleSubmit = jest.fn();
      const wrapper = mount(
          <Login handleSubmit={handleSubmit}/>
      );
      const instance = wrapper.instance();
      const submitBtn = app.find('#sign-in')
      submitBtn.simulate('click')
      expect(handleSubmit).toHaveBeenCalled();
    });
  }

You need to call this test function handleSubmit in your login component either as a part of onSubmit or export whole onSubmit from upper components. Example login code with importing part of login function

import React from 'react'

function Login( {handleSubmit}) {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');

    const onSubmit = async (e) => {
        if (handleSubmit) {
          handleSubmit()
        }
        e.preventDefault();
        // ....api calLS
    }
    return (
        <div>
             <form onSubmit={onSubmit} className="login">
    
            <input type="email" id="email-input" name="email" value={email} onChange={e => setEmail(e.target.value)} />
        
            <input type="password" id="password-input" name="password" value={password} onChange={e =>setPassword(e.target.value)} />
            
            <input type="submit" value="Submit" />
             </form> 
        </div>
    )
}

export default Login

Example login code with importing of submit function

import React from 'react'

function Login( {handleSubmit}) {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
   
    // handleSubmit is imported with props
 
    return (
        <div>
             <form onSubmit={handleSubmit} className="login">
    
            <input type="email" id="email-input" name="email" value={email} onChange={e => setEmail(e.target.value)} />
        
            <input type="password" id="password-input" name="password" value={password} onChange={e =>setPassword(e.target.value)} />
            
            <input type="submit" value="Submit" />
             </form> 
        </div>
    )
}

export default Login

like image 132
Ryu Avatar answered Sep 28 '22 08:09

Ryu