Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test text input with react and jest

I have a simple SearchBar component in a small test project of mine. This SearchBar consists mainly of a text input and a button, where the button click executes a callback with the text from the input field.

My Searchbar.render method looks like this:

  return (
    <FormGroup controlId="keywords">
      <InputGroup>
        <FormControl type="text"
                     placeholder="Keywords…"
                     value={this.state.keywords}
                     onChange={this.updateKeywords} />
        <InputGroup.Button
          onClick={() => {this.props.onSearch(this.state.keywords);}}
          ref="searchInput">
          <Button ref="searchButton">
            <Glyphicon glyph="search"/>
          </Button>
        </InputGroup.Button>
      </InputGroup>
    </FormGroup>
  );

I've written a test for it using jest:

it("should adjust keywords and trigger onSearch correctly", () => {
  const handleSearch = jest.fn();

  const searchBar = ReactTestUtils.renderIntoDocument(
    <Searchbar onSearch={handleSearch}/>
  );
  expect(searchBar.state.keywords).toBe("");

  const button = ReactDOM.findDOMNode(searchBar.refs.searchButton);
  const input = ReactDOM.findDOMNode(searchBar.refs.searchInput);

  ReactTestUtils.Simulate.change(input, {target: {value: "test"}});

  ReactTestUtils.Simulate.click(button);
  expect(handleSearch).toHaveBeenCalledWith("test");
});

Now the callback in this test works and the function stored in callMe get's called as expected. The SearchBar also works in my application so I think that the SearchBar code is correct. But when I use npm test to run my tests the test fails with:

expect(jest.fn()).toHaveBeenCalledWith(expected)

Expected mock function to have been called with:
  ["test"]
But it was called with:
  [""]

In the comments Andreas Köberle pointed me to the problem that the updateKeywords method appears to not be called which should be the reason for the failing test. Sadly I cannot figure out why this method isn't called in the test.

like image 681
Jakob Runge Avatar asked Dec 30 '16 13:12

Jakob Runge


People also ask

Can you test React with Jest?

Jest is a JavaScript testing framework that allows developers to run tests on JavaScript and TypeScript code and can be easily integrated with React JS. Open the package. json, and you will find that when you use create-react-app for creating a react project, it has default support for jest and react testing library.

Can you test React hooks with Jest?

Testing React Hooks with Jest and Enzyme. Jest and Enzyme are tools used for testing React apps. Jest is a JavaScript testing framework used to test JavaScript apps, and Enzyme is a JavaScript testing utility for React that makes it easier to assert, manipulate, and traverse your React components' output.

Does React scripts test use Jest?

create-react-app uses both Jest and React Testing Library by default. Additionally, [react-scripts] automatically sets up our server to watch for changes, so if the test file is modified, the server automatically compiles and runs the test without needing to restart your server.


1 Answers

You have to pass the event data by yourself, as it does not really trigger the event on a DOM element. From the docs:

You will have to provide any event property that you're using in your component (e.g. keyCode, which, etc...) as React is not creating any of these for you.

Is also common to just put a spy function as callback into your component, and test this after simulate the event.

const handleSearch = jest.fn();
const searchBar = ReactTestUtils.renderIntoDocument(
    <Searchbar onSearch={handleSearch}/>
);
ReactTestUtils.Simulate.change(input, {target: {value: 'test'}});
expect(handleSearch).toHaveBeenCalledWith('test')
like image 77
Andreas Köberle Avatar answered Nov 09 '22 22:11

Andreas Köberle