Testing input.focus() in Enzyme

Per React 16.3 updates... using createRef for anyone visiting this post today, if you rearrange the original component to use the new ref api

class InputBox extends PureComponent {
    constructor(props) {
        super(props);
        this.inputRef = React.createRef();
    }
    componentDidMount() {
        this.inputRef.current.focus();
    }
    render() {
        return (
            <input
                ref={this.inputRef}
            />
        );
    }
}

Then in your test spec

it("Gives immediate focus on to name field on load", () => {
    const wrapper = mount(<InputBox />);
    const { inputRef } = wrapper.instance();

    jest.spyOn(inputRef.current, "focus");

    wrapper.instance().componentDidMount();
    expect(inputRef.current.focus).toHaveBeenCalledTimes(1);
});

Notice the use of the inputRef.current attribute which references the currently assigned DOM node.


Other approach is to test if element gains focus, i.e. focus() is called on node element. To achieve this, focused element need to be referenced via ref tag like it takes place in your example – reference was assigned to this.inputBox. Consider example below:

const wrapper = mount(<FocusingInput />);
const element = wrapper.instance().inputBox; // This is your input ref

spyOn(element, 'focus');

wrapper.simulate('mouseEnter', eventStub());

setTimeout(() => expect(element.focus).toHaveBeenCalled(), 250);

This example uses Jasmine's spyOn, though you can use any spy you like.


You can use mount instead of shallow. Then you can compare document.activeElement and the input DOM node for equality.

const output = mount(<MyFocusingComponent/>);

assert(output.find('input').node === document.activeElement);

See https://github.com/airbnb/enzyme/issues/316 for more details.