How to test Textinput with onKeyPress

1k views Asked by At

I want to test an input field with jest and enzyme

  test('Filter Test', async () => {
    const setFilter = jest.fn();

    const bar = mount(
      <TestWrapper>
        <SearchAndFilterBar textFilters={textFilters} filterButtons={filterButtons} setFilterQuery={setFilter} />
      </TestWrapper>,
    );

    bar
      .find('#minValue')
      .simulate('change', { target: { value: '23' } })
      .simulate('keypress', { key: 'Enter', code: 13 });

    expect(setFilter).toHaveBeenCalled();
  });

the code is the following

<TextInput
   onKeyPress={onMinKeyPressHandler}
   id={'minValue'}
   invalid={false}
   value={minValue}
   onChange={e => !isNaN(Number(e.target.value)) && setMinValue(e.target.value)}
   placeholder={valueType}
/>

The problem is that the onMinKeyPressHandler is not called called by the test.
Does someone see why the test is not working?

1

There are 1 answers

1
Matt Carlotta On BEST ANSWER

I'm not able to replicate your issue. That said, I think you can simplify your component to, instead of being a text input, being a number input.

By setting type="number" and adding a min="0", you can skip checking whether or not it's a valid number in your onChange callback.

I created a codesandbox with working tests (click the Tests tab to run the tests):

Edit Testing Input - OnKeyPress

If your set up is different, fork the codesandbox, adjust it as needed and add it in the comments below.


components/Input/index.js

import React from "react";
import PropTypes from "prop-types";

const Input = ({
  handleChange,
  handleKeyPress,
  name,
  min,
  placeholder,
  type,
  value
}) => (
  <input
    style={{ marginRight: 5 }}
    name={name}
    type={type}
    min={min}
    placeholder={placeholder}
    value={value}
    onChange={handleChange}
    onKeyPress={handleKeyPress}
  />
);

Input.propTypes = {
  handleChange: PropTypes.func.isRequired,
  handleKeyPress: PropTypes.func.isRequired,
  min: PropTypes.string,
  name: PropTypes.string.isRequired,
  placeholder: PropTypes.string,
  type: PropTypes.string.isRequired,
  value: PropTypes.string
};

export default Input;

components/Input/__tests__/Input.test.js

import React from "react";
import { configure, mount } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import Input from "../index";

configure({ adapter: new Adapter() });

const handleChange = jest.fn();
const handleKeyPress = jest.fn();
const name = "searchNumber";

const initProps = {
  handleChange,
  handleKeyPress,
  name,
  min: "0",
  placeholder: "Search for a number...",
  type: "number",
  value: ""
};

const value = "test";
const key = "Enter";

describe("Input", () => {
  let wrapper;
  beforeEach(() => {
    wrapper = mount(<Input {...initProps} />);
  });

  afterEach(() => {
    handleChange.mockClear();
    handleKeyPress.mockClear();
  });

  it("renders without errors", () => {
    expect(wrapper.find("input").exists()).toBeTruthy();
  });

  it("calls handleChange when a value is typed in", () => {
    wrapper.find("input").simulate("change", { target: { name, value } });

    expect(handleChange).toBeCalledWith(
      expect.objectContaining({ target: { name, value } })
    );
  });

  it("calls handleKeyPress when the Enter key is pressed", () => {
    wrapper.find("input").simulate("keypress", { key, value });

    expect(handleKeyPress).toBeCalledWith(
      expect.objectContaining({ key, value })
    );
  });
});