问题
i want to mock handleClick event of my TodoForm component.
TodoForm.jsx
import React, { Component } from "react";
export class TodoForm extends Component {
handleClick = () => {
console.log("handle click is called");
}
render() {
return (
<div>
<button onClick={this.handleClick}>Clik</button>
</div>
)
}
}
in TodoForm.test.js
import React from 'react'
import { mount, shallow } from 'enzyme'
import { TodoForm } from "../TodoForm";
it("must call the mock function when button is clicked", () => {
const mocked = jest.fn();
const wrapper = mount(<TodoForm />);
wrapper.instance().handleClick = mocked;
wrapper.update();
wrapper.find("button").simulate("click");
expect(mocked).toHaveBeenCalled();
})
the test fails with "Expected mock function to have been called, but it was not called."
instead of calling the mock function it calls the real implementation.
I am using create-react-app,
react:16.6.3,
enzyme: 3.8.0,
enzyme-adapter-react-16 :1.7.1
回答1:
This is a known issue with Enzyme. update()
doesn't cause a re-render. This results in triggering original handleClick
, because render
function was called before mocking the method.
A workaround is to use wrapper.instance().forceUpdate()
instead of wrapper.update()
.
Testability is one of several reasons to prefer bound prototype methods over arrow instance methods.
来源:https://stackoverflow.com/questions/53742117/how-to-mock-a-react-components-event-when-fat-arrow-function-is-used-as-event-h