web-dev-qa-db-fra.com

Simulation cliquez sur le document ReactJS/JSDom

J'écris donc des tests de code qui ajoutent un événement de clic sur le document. J'utilise les configurations JSDom, ReactJS et Mocha/Chai. J'ai essayé le code suivant dans un test:

document.addEventListener('click', function() {
  console.log('test');
});
React.addons.TestUtils.Simulate.click(document);
//also tried React.addons.TestUtils.Simulate.click(document.body);

cependant, ce code ne produit pas l'écho que j'attends.

Existe-t-il un moyen de simuler un clic, une incrustation, etc. sur le document avec JSDom et ReactJS?

UPDATE

Pour Nick répond, j'ai essayé d'ajouter ce code au test:

document.body.addEventListener('click', function() {
  console.log('test');
});

document.body.click();

et je ne reçois pas la sortie du journal de la console. Je ne suis pas sûr s'il y a un problème avec JSDom et ce genre de chose.

Si je ne peux pas tester ce code à l'unité, c'est bien, il existe déjà un code que je ne peux pas tester à l'heure actuelle (code qui nécessite un vrai DOM pour pouvoir obtenir des largeurs, des hauteurs, etc.) mais je aimerait pouvoir tester la plupart du code sur les tests unitaires (et je ne suis pas intéressé par l’utilisation de PhantomJS pour les tests unitaires). Mes tests d'intégration couvriront ce type de code.

UPDATE2

Une autre chose à noter est que lorsque je console.log(document);, je vois un objet attaché à la propriété _listeners pour click, donc je sais que l'événement est en cours de rattachement, il ne semble tout simplement pas être en cours d'exécution.

13
ryanzec

Update: document.body.click fonctionnera dans un navigateur, mais pour jsdom, vous devez créer manuellement l'événement:

document.body.addEventListener('click', function() {
  console.log('test');
});

var evt = document.createEvent("HTMLEvents");
evt.initEvent("click", false, true);
document.body.dispatchEvent(evt)

Le code ci-dessus fonctionne pour moi dans Jest et devrait également fonctionner avec "solo" jsdom.

Mise à jour des vacances automne 2018 ????

Les outils de simulation d’événements se sont beaucoup améliorés. J'ai actuellement modifié mon approche pour utiliser l'excellente react-testing-library / afin de restituer mes composants et les événements de dispatch:

import {render, fireEvent} from 'react-testing-library'

test('example', () => {
  const handleClick = jest.fn()

  const {getByText} = render(<div><button onClick={handleClick}>Click Me</button></div>)
  fireEvent.click(getByText('Click Me'))

  expect(handleClick).toHaveBeenCalled()
})

Bien que je croie toujours dans les tests de bout en bout avec quelque chose comme marionnettiste ou sélénium (ou cyprès!) Fournir le plus haut niveau de confiance que quelque chose fonctionne réellement, cela fournit une énorme quantité de valeur sans tests polluants avec la création manuelle d'événements.

26
Nick Tomlin

React.addons.TestUtils.Simulate ne fonctionne qu'avec les événements virtuels. Si vous souhaitez distribuer des événements natifs, vous pouvez le faire directement avec l’API DOM.

Lors de la simulation d'un clic, si vous avez un composant qui rend ceci:

<div>
   <button onClick={alert}>click me</button>
</div>

Et vous avez une référence au <button/> dans une variable appelée 'buttonEl', et lancez ceci:

React.addons.TestUtils.Simulate.click(buttonEl, 'hello world');

Vous obtiendrez une alerte avec «hello world» dedans. Tout ce que test utils fait, c’est créer l’événement virtuel et le laisser bouillonner dans l’arborescence des doms virtuels, en appelant les gestionnaires d’événements en cours de route.

6
FakeRainBrigand

Créez simplement une Event et envoyez-la:

// Add an event listeners to the document
document.addEventListener('click', function() {
    console.log('test');
});

// Create a new `click` event and `dispatch` it
var event = new MouseEvent('click')
document.dispatchEvent(event)
0
Riccardo Bartoli

Event.initEvent() est obsolète et le constructeur Event() devrait maintenant être utilisé à la place.

// Add a click event listener to the document
document.addEventListener('click', function() {
    console.log('test');
});

// Create a click event with optional event initialisers: bubbles, cancelable and composed
var evt = new Event('click', { bubbles: false, cancelable: false, composed: false });

// Event can then be dispatched against any element, not only the document
document.dispatchEvent(evt);
myDiv.dispatchEvent(evt);

La prise en charge du navigateur est bonne, à l’exception d’Internet Explorer.

Références:

0
Wayne