manas
manas

Reputation: 6400

How to simulate click event with mock function in enzyme and Jest?

I have foo component I want to simulate button click with a mock function

 export default class Foo extends Component {
        btnClick() {
            console.log("hello...");
        }
        render() {
            return (
                <div>
                    <h2>Hello</h2>
                    <button onClick={this.btnClick.bind(this)} id="btn">Click</button>
                </div>
            );
        }
    }

My test code looks like following

 it("must call the mock method with button click", () => {

        const wrapper = mount(<Foo />);
        wrapper.instance().btnClick = jest.fn(() => {
            return 8;
        });

        wrapper.update();

        const btn = wrapper.find("#btn");
        btn.simulate("click");

        expect(wrapper.instance().btnClick).toHaveBeenCalled();
    })

simulation of click event calls the components real method instead of calling the mock method.

I know it can be done by passing mock function as props to the <Foo/> component.

I want to know is there any other way to simulate click(i.e private to the component) with mock method.

Upvotes: 2

Views: 21135

Answers (2)

Allan
Allan

Reputation: 37

import React from "react";
import { shallow } from "enzyme";
import Foo from "path/Foo"

describe("Executes a handler function", () => {
  it("must call the mock method with button click", () => {
    const wrapper = shallow(<Foo />);
    const button = wrapper.find("button");
    const instance = wrapper.instance();

    instance.btnClick = jest.fn(instance.btnClick);

    button.simulate("click");
    expect(instance.btnClick).toHaveBeenCalled();
  });
});

Upvotes: -1

Alexandre Borela
Alexandre Borela

Reputation: 1626

The problem was that you were rendering the component first and then trying to mock the function, by that time, you already created a bounded copy, the solution then is to mock directly into the prototype.

import Adapter from 'enzyme-adapter-react-16'
import React, {Component} from 'react'
import {configure, mount} from 'enzyme'

configure({adapter: new Adapter()})

export default class Foo extends Component {
  btnClick() {
    console.log("hello...")
  }

  render() {
    return (
      <div>
        <h2>Hello</h2>
        <button
            id="btn"
            onClick={this.btnClick.bind(this)}
        >
          Click
        </button>
      </div>
    )
  }
}

it("must call the mock method with button click", () => {
    let spy =  jest.spyOn(Foo.prototype, 'btnClick')
      .mockImplementation(() => 8)

    const wrapper = mount(<Foo/>)
    const btn = wrapper.find("#btn")
    btn.simulate("click")

    expect(spy).toHaveBeenCalled()
})

Upvotes: 4

Related Questions