web-dev-qa-db-fra.com

Test de input.focus () en Enzyme

Quelqu'un peut-il m'aider à tester input.focus () dans enzyme.J'écris le script avec react.Mon code est ci-dessous.

public inputBox: any;

componentDidUpdate = () => {
    setTimeout(() => {
        this.inputBox.focus();
    }, 200);
}

render() {
    return (
        <div>
            <input
                type = 'number'
                ref = {element => this.inputBox = element } />
        </div>
    );
}
14
Sachin

Une autre approche consiste à vérifier si l'élément gagne le focus, c'est-à-dire que focus() est appelé sur l'élément node. Pour ce faire, les éléments ciblés doivent être référencés via la balise ref, comme cela se produit dans votre exemple - la référence a été attribuée à this.inputBox. Considérez l'exemple ci-dessous:

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);

Cet exemple utilise spyOn de Jasmine, bien que vous puissiez utiliser n'importe quel espion que vous aimez. 

6
mckomo

Vous pouvez utiliser mount au lieu de shallow . Vous pouvez ensuite comparer document.activeElement et le nœud DOM d'entrée pour vérifier l'égalité.

const output = mount(<MyFocusingComponent/>);

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

Voir https://github.com/airbnb/enzyme/issues/316 pour plus de détails.

17
whatknight

Per React 16.3 met à jour ... en utilisant createRef pour ceux qui visitent ce post aujourd'hui, si vous modifiez le composant d'origine pour utiliser le nouvel ap

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

Puis dans vos spécifications de test

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);
});

Notez l'utilisation de l'attribut inputRef.current qui fait référence au nœud DOM actuellement attribué.

8
Prancer

Je viens d'avoir le même problème et résolu en utilisant l'approche suivante:

Ma configuration est Jest (react-create-app) + Enzyme:

    it('should set the focus after render', () => {
      // If you don't create this element you can not access the 
      // document.activeElement or simply returns <body/>
      document.body.innerHTML = '<div></div>'

      // You have to tell Enzyme to attach the component to this
      // newly created element
      wrapper = mount(<MyTextFieldComponent />, {
        attachTo: document.getElementsByName('div')[0]
      })

      // In my case was easy to compare using id 
      // than using the whole element
      expect(wrapper.find('input').props().id).toEqual(
        document.activeElement.id
      )
    })
1
thiagoxvo