User3000
User3000

Reputation: 65

React testing history push using jest

I am trying to test a menu bar, which handles routing to some pages using history.push. I am using Primereact Menubar component.

 class MenubarComponent extends React.Component {

    constructor() {
        super();
        this.state = {
            items: [
                {
                    label: "Home",
                    icon: "pi pi-home",
                    command: () => (this.props.history.push("/"))
                },
                {
                    label: "About",
                    icon: "pi pi-info",
                    command: () => (this.props.history.push("/about"))
                }
            ]
        }
    }

    render() {
        return (
            <Menubar model={this.state.items}/>
        )
    }
}

export default withRouter(MenubarComponent)

How can I verify that when I click on a menubar button, it takes me to the correct page?

     describe('MenubarComponent', () => {
        it('should navigate on menuitem click', () => {
            const menubarItemsMock = jest.fn();
            const item = {
              label: "Home",
              icon: "pi pi-home",
              command: () => (this.props.history.push("/"))
           }
            const wrapper = shallow(<MenubarComponent/>)
            //??
        })
    })

Upvotes: 0

Views: 7226

Answers (1)

Lin Du
Lin Du

Reputation: 102287

Since history is a prop of the component, you can create a mocked history object and pass it to the component. In order to test the command function in the items array. You need to use wrapper.state('items') to get the items array in your test case, then you get access and test command function.

Here is the unit test solution:

menubarComponent.jsx:

import React from 'react';
import { withRouter } from 'react-router-dom';
import Menubar from './menubar';

class MenubarComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [
        {
          label: 'Home',
          icon: 'pi pi-home',
          command: () => this.props.history.push('/'),
        },
        {
          label: 'About',
          icon: 'pi pi-info',
          command: () => this.props.history.push('/about'),
        },
      ],
    };
  }

  render() {
    return <Menubar model={this.state.items} />;
  }
}

export default withRouter(MenubarComponent);

menubar.jsx:

import React from 'react';

export default function Menubar() {
  return <div></div>;
}

menubarComponent.test.jsx:

import MenubarComponent from './menubarComponent';
import { shallow } from 'enzyme';
import React from 'react';

describe('61476449', () => {
  it('should pass', () => {
    const mProps = { history: { push: jest.fn() } };
    const wrapper = shallow(<MenubarComponent.WrappedComponent {...mProps}></MenubarComponent.WrappedComponent>);
    const items = wrapper.state('items');
    items[0].command();
    expect(mProps.history.push).toBeCalledWith('/');
    items[1].command();
    expect(mProps.history.push).toBeCalledWith('/about');
  });
});

unit test results with coverage report:

 PASS  stackoverflow/61476449/menubarComponent.test.jsx (8.848s)
  61476449
    ✓ should pass (7ms)

----------------------|---------|----------|---------|---------|-------------------
File                  | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------------------|---------|----------|---------|---------|-------------------
All files             |   93.75 |      100 |   83.33 |   93.33 |                   
 menubar.jsx          |   66.67 |      100 |       0 |   66.67 | 4                 
 menubarComponent.jsx |     100 |      100 |     100 |     100 |                   
----------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.886s, estimated 10s

Upvotes: 3

Related Questions