Test-Utilities
Import
import ReactTestUtils from 'react-dom/test-utils'; // ES6
var ReactTestUtils = require('react-dom/test-utils'); // ES5 mit npm
Übersicht
ReactTestUtils
bieten eine einfache Möglichkeit, React-Komponenten in einem Test-Framework deiner Wahl zu testen. Bei Facebook benutzen wir Jest für schmerzfreie Javascript-Tests. Du kannst das React-Tutorial auf Jest’s Webseite besuchen, um Jest zu lernen.
Hinweis:
Wir empfehlen die Verwendung der React Testing Library, die konzipiert wurde, um das Schreiben von Tests zu ermöglichen, in denen Komponenten auf die gleiche Weise verwendet werden wie von Endnutzern.
Für React-Versionen <= 16 macht es die Enzyme Bibliothek einfach, die Ausgabe deiner React-Komponenten zu prüfen, zu manipulieren und zu durchlaufen.
act()
mockComponent()
isElement()
isElementOfType()
isDOMComponent()
isCompositeComponent()
isCompositeComponentWithType()
findAllInRenderedTree()
scryRenderedDOMComponentsWithClass()
findRenderedDOMComponentWithClass()
scryRenderedDOMComponentsWithTag()
findRenderedDOMComponentWithTag()
scryRenderedComponentsWithType()
findRenderedComponentWithType()
renderIntoDocument()
Simulate
Referenz
act()
Um eine Komponente für Assertionen vorzubereiten, setze den Code, der sie rendert und aktualisiert, in einen act()
-Aufruf. Damit läuft der Test so ähnlich ab, wie React auch im Browser funktioniert.
Hinweis
Falls du
react-test-renderer
verwendest, kannst du dessenact
-Export verwenden, der sich gleich verhält.
Stelle dir als Beispiel vor, du hast diese Counter
-Komponente:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {count: 0};
this.handleClick = this.handleClick.bind(this);
}
componentDidMount() {
document.title = `Du hast ${this.state.count} Mal geklickt`;
}
componentDidUpdate() {
document.title = `Du hast ${this.state.count} Mal geklickt`;
}
handleClick() {
this.setState(state => ({
count: state.count + 1,
}));
}
render() {
return (
<div>
<p>Du hast {this.state.count} Mal geklickt</p>
<button onClick={this.handleClick}>
Klick mich
</button>
</div>
);
}
}
So können wir sie testen:
import React from 'react';
import ReactDOM from 'react-dom/client';
import { act } from 'react-dom/test-utils';import Counter from './Counter';
let container;
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
document.body.removeChild(container);
container = null;
});
it('kann einen Counter rendern und updaten', () => {
// Erstes Rendern und componentDidMount testen
act(() => { ReactDOM.createRoot(container).render(<Counter />); }); const button = container.querySelector('button');
const label = container.querySelector('p');
expect(label.textContent).toBe('Du hast 0 Mal geklickt');
expect(document.title).toBe('Du hast 0 Mal geklickt');
// Zweites Rendern und componentDidUpdate testen
act(() => { button.dispatchEvent(new MouseEvent('click', {bubbles: true})); }); expect(label.textContent).toBe('Du hast 1 Mal geklickt');
expect(document.title).toBe('Du hast 1 Mal geklickt');
});
- Vergiss nicht, dass das Abschicken von DOM-Events nur funktioniert, wenn der DOM-Container zum
document
hinzugefügt wurde. Du kannstReact Testing Library
zur Hilfe nehmen, um Boilerplate-Code zu reduzieren. - Das
recipes
Dokument enthält mehr Details dazu, wie sichact()
verhält, mit Beispiele und Anwendungsgebieten.
mockComponent()
mockComponent(
componentClass,
[mockTagName]
)
Übergebe dieser Methode ein gemocktes Komponenten-Modul, um es mit nützlichen Methoden zu erweitern, mit denen es als Dummy-React-Komponente verwendet werden kann. Anstatt wie üblich zu rendern, wird die Komponente zu einem einfachen <div>
(oder zu einem anderen Tag
, falls mockTagName
angegeben wurde), das die ihr übergegebenen Children-Elemente enthält.
Hinweis:
mockComponent()
ist eine veraltete API. Wir empfehlen, stattdessenjest.mock()
zu verwenden.
isElement()
isElement(element)
Gibt true
zurück, falls element
ein React-Element ist.
isElementOfType()
isElementOfType(
element,
componentClass
)
Gibt true
zurück, falls element
ein React-Element vom Typ React componentClass
ist.
isDOMComponent()
isDOMComponent(instance)
Gibt true
zurück, falls instance
eine DOM-Komponente (z. B. ein <div>
oder <span>
) ist.
isCompositeComponent()
isCompositeComponent(instance)
Gibt true
zurück, falls instance
eine benutzerdefinierte Komponente, z. B. eine Klasse oder Funktion, ist.
isCompositeComponentWithType()
isCompositeComponentWithType(
instance,
componentClass
)
Gibt true
zurück, falls instance
eine Komponente vom Typ React componentClass
ist.
findAllInRenderedTree()
findAllInRenderedTree(
tree,
test
)
Durchläuft alle Komponenten in tree
und sammelt alle Komponenten, bei denen test(component)
true
ist. Das ist für sich allein genommen nicht besonders nützlich, wird aber als Primitive für andere Test-Utilities verwendet.
scryRenderedDOMComponentsWithClass()
scryRenderedDOMComponentsWithClass(
tree,
className
)
Findet alle DOM-Elemente von Komponenten im gerenderten Baum, bei denen der Klassennamen der Komponenten mit className
übereinstimmt.
findRenderedDOMComponentWithClass()
findRenderedDOMComponentWithClass(
tree,
className
)
Verhält sich wie scryRenderedDOMComponentsWithClass()
, erwartet aber genau ein Resultat und gibt dieses zurück. Gibt einen Fehler aus, falls es mehr oder weniger als eine Übereinstimmung gibt.
scryRenderedDOMComponentsWithTag()
scryRenderedDOMComponentsWithTag(
tree,
tagName
)
Findet alle DOM-Elemente von Komponenten im gerenderten Baum, bei denen der Tagname der Komponenten mit tagName
übereinstimmt.
findRenderedDOMComponentWithTag()
findRenderedDOMComponentWithTag(
tree,
tagName
)
Verhält sich wie scryRenderedDOMComponentsWithTag()
, erwartet aber genau ein Resultat und gibt dieses zurück. Gibt einen Fehler aus, falls es mehr oder weniger als eine Übereinstimmung gibt.
scryRenderedComponentsWithType()
scryRenderedComponentsWithType(
tree,
componentClass
)
Findet alle Instanzen von Komponenten, deren Typ mit componentClass
übereinstimmt.
findRenderedComponentWithType()
findRenderedComponentWithType(
tree,
componentClass
)
Verhält sich wie scryRenderedComponentsWithType()
, erwartet aber genau ein Resultat und gibt dieses zurück. Gibt einen Fehler aus, falls es mehr oder weniger als eine Übereinstimmung gibt.
renderIntoDocument()
renderIntoDocument(element)
Rendert ein React-Element in einen separaten DOM-Knoten im Dokument. Diese Funktion benötigt ein DOM. Effektiv ist sie äquivalent zu:
const domContainer = document.createElement('div');
ReactDOM.createRoot(domContainer).render(element);
Hinweis:
window
,window.document
undwindow.document.createElement
müssen global verfügbar sein, bevor duReact
importierst. Ansonsten denkt React, dass es nicht auf das DOM zugreifen kann, und Methoden wiesetState
werden nicht funktionieren.
Andere Utilities
Simulate
Simulate.{eventName}(
element,
[eventData]
)
Simuliere das Abschicken eines Events auf einen DOM-Knoten mit optionalen eventData
-Eventdaten.
Simulate
hat eine Methode für jedes Event, das React versteht.
Ein Element anklicken
// <button ref={(node) => this.button = node}>...</button>
const node = this.button;
ReactTestUtils.Simulate.click(node);
Den Wert eines Input-Feldes verändern und dann ENTER drücken
// <input ref={(node) => this.textInput = node} />
const node = this.textInput;
node.value = 'Giraffe';
ReactTestUtils.Simulate.change(node);
ReactTestUtils.Simulate.keyDown(node, {key: "Enter", keyCode: 13, which: 13});
Hinweis
Du musst jede Event-Eigenschaft angeben, die du in deiner Komponente verwendest (z. B. keyCode, which, etc.), da React keine davon für dich erstellt.