Enzyme testing error, Method “simulate” is meant to be run on 1 node. 0 found instead

I'm new at testing and I'm trying to test react app using enzyme,

I want to test the changing in the value of (email input), when I run my test I get this error! everything looks OK to me, what is the problem!

""""""""""""{ Method “simulate” is meant to be run on 1 node. 0 found instead.}"""""""""

my component :

import React, { useState } from 'react';
import login from '../../../services/accountService';
import validate from '../../../utility/loginValidate';
import { Button, Error, Form, Input, Label, NavLink, Sign, SignBtn } from './signin-style';

/**
 * Component to log in the website if you have valid information, and display errors if the information is invalid!
 */
function Signin() {
  const [email, setemail] = useState('');
  const [password, setPassword] = useState('');
  const [errors, setErrors] = useState(null);

  /**
   *this methode called when the user presses the submit button, first it will check if there is errors, if not it will submit the form!
   *
   * @param {onSubmit} event click on submit button event!
   */
  const handleSubmit = (event) => {
    event.preventDefault();

    /**
     * Function that check if the user inserted wrong information and put it on @error variable!, then it will update the @errors state!
     */
    const error = validate(email, password);
    setErrors(error);
  };

  /**
   * Method that handle the change on { email input } by taking the input value and setting it on @email state!
   *
   * @param {onChange} event when user type in email input!
   */
  const handleemailChange = (event) => {
    const user = event.currentTarget.value;
    setemail(user);
  };

  /**
   *  Method that handle the change on { password input } by taking the input value and setting it on @password state!
   *
   * @param {onChange} event  when user type in password input!
   */
  const handlePasswordChange = (event) => {
    const pass = event.currentTarget.value;
    setPassword(pass);
  };

  return (
    <Sign>
      <h1>Sign In</h1>
      <NavLink to="/login">Need an account?</NavLink>
      {errors ? <Error>* Invalid email or password!</Error> : null}
      <Form onSubmit={handleSubmit}>
        <div>
          <Label htmlFor="email">
            <Input
              value={email}
              onChange={handleemailChange}
              id="email"
              type="text"
              placeholder="Email"
            />
          </Label>
        </div>
        <div>
          <Label htmlFor="password">
            <Input
              value={password}
              onChange={handlePasswordChange}
              id="password"
              type="password"
              placeholder="Password"
            />
          </Label>
        </div>
        <SignBtn>
          <Button onClick={() => login({ email, password })} type="submit">
            Sign in
          </Button>
        </SignBtn>
      </Form>
    </Sign>
  );
}

export default Signin;

my test :

  let wrapper;
  beforeEach(() => {
    wrapper = shallow(<Signin />);
  });

  it('should render Signin component without crashing', () => {
    expect(wrapper).toMatchSnapshot();
  });

  it('should check email input value', () => {
    const emailInput = wrapper.find('Input[type="email"]');
    emailInput.simulate('change', { target: { value: 'alaa@gmail.com' } });
    expect(emailInput.prop('value')).toEqual('alaa@gmail.com');
  });

  
});

1 answer

  • answered 2021-03-02 14:22 Dario

    You are selecting the input by type [type="email"] but you don't have such element, your inputs are both of type text; this is why you get the 0 found instead error.

    You could try selecting the input with just its id with:

    const emailInput = wrapper.find('#email');

    Furthermore:

    1. Your handle callback use currentTarget, so you should simulate with it instead of just target: emailInput.simulate('change', { currentTarget: { value: 'alaa@gmail.com' } });
    2. emailInput still points on old wrapper (and value), so you need to .find() the element again: expect(wrapper.find('#email').prop('value')).toBe('alaa@gmail.com');