Test Renderer
Importowanie
import TestRenderer from 'react-test-renderer'; // ES6
const TestRenderer = require('react-test-renderer'); // ES5 z zainstalowanym npm
Ogólne informacje
Paczka ta udostępnia narzędzie, które renderuje komponenty reactowe do czysto javascriptowych obiektów, bez użycia drzewa DOM czy natywnego środowiska mobilnego.
Istotą tej paczki jest łatwość wygenerowania “migawki” (ang. snapshot) hierarchii widoków (podobnej do drzewa DOM), wyrenderowanej przez komponent z React DOM lub React Native bez pomocy przeglądarki czy jsdom.
Przykład:
import TestRenderer from 'react-test-renderer';
function Link(props) {
return <a href={props.page}>{props.children}</a>;
}
const testRenderer = TestRenderer.create(
<Link page="https://www.facebook.com/">Facebook</Link>
);
console.log(testRenderer.toJSON());
// { type: 'a',
// props: { href: 'https://www.facebook.com/' },
// children: [ 'Facebook' ] }
Przy pomocy funkcjonalności biblioteki Jest do generowania snapshotów można automatycznie zapisać do pliku kopię drzewa w formacie JSON, a w teście sprawdzać, czy się ono nie zmieniło (Więcej informacji na ten temat).
Zwrócone drzewo można również przeszukiwać w celu znalezienia konkretnych węzłów i sprawdzenia ich właściwości.
import TestRenderer from 'react-test-renderer';
function MyComponent() {
return (
<div>
<SubComponent foo="bar" />
<p className="my">Cześć</p>
</div>
)
}
function SubComponent() {
return (
<p className="sub">Potomek</p>
);
}
const testRenderer = TestRenderer.create(<MyComponent />);
const testInstance = testRenderer.root;
expect(testInstance.findByType(SubComponent).props.foo).toBe('bar');
expect(testInstance.findByProps({className: "sub"}).children).toEqual(['Potomek']);
TestRenderer
Instancja TestRenderer
testRenderer.toJSON()
testRenderer.toTree()
testRenderer.update()
testRenderer.unmount()
testRenderer.getInstance()
testRenderer.root
TestInstance
testInstance.find()
testInstance.findByType()
testInstance.findByProps()
testInstance.findAll()
testInstance.findAllByType()
testInstance.findAllByProps()
testInstance.instance
testInstance.type
testInstance.props
testInstance.parent
testInstance.children
Dokumentacja
TestRenderer.create()
TestRenderer.create(element, options);
Tworzy instancję TestRenderer
przy użyciu przekazanego elementu reactowego. Nie korzysta z prawdziwego drzewa DOM, lecz renderuje całe drzewo komponentów do pamięci, aby można było wykonać na nim asercje. Zwraca instancję TestRenderera.
TestRenderer.act()
TestRenderer.act(callback);
Podobnie jak funkcja pomocnicza act()
z react-dom/test-utils
, TestRenderer.act
przygotowuje komponent do późniejszych asercji. Używaj tej wersji funkcji act()
do opakowania wywołań TestRenderer.create
i testRenderer.update
.
import {create, act} from 'react-test-renderer';
import App from './app.js'; // Testowany komponent
// wyrenderuj komponent
let root;
act(() => {
root = create(<App value={1}/>)
});
// wykonaj sprawdzenia na korzeniu drzewa
expect(root.toJSON()).toMatchSnapshot();
// zaktualizuj komponent przy użyciu innych właściwości
act(() => {
root.update(<App value={2}/>);
})
// wykonaj sprawdzenia na korzeniu drzewa
expect(root.toJSON()).toMatchSnapshot();
testRenderer.toJSON()
testRenderer.toJSON()
Zwraca obiekt reprezentujący wyrenderowane drzewo. W drzewie znajdą się wyłącznie węzły specyficzne dla platformy, np. <div>
lub <View>
, wraz ze swoimi właściwościami. Nie zostaną wyrenderowane natomiast żadne niestandardowe komponenty użytkownika. Funkcja przydaje się przy testowaniu za pomocą snapshotów.
testRenderer.toTree()
testRenderer.toTree()
Zwraca obiekt reprezentujący wyrenderowane drzewo. W przeciwieństwie do toJSON()
, ta reprezentacja jest bardziej szczegółowa i zawiera również niestandardowe komponenty użytkownika. Prawdopodobnie ta funkcja nigdy ci się nie przyda, chyba że piszesz w oparciu o tę paczkę własną bibliotekę do testów.
testRenderer.update()
testRenderer.update(element)
Przy użyciu nowego elementu głównego ponownie renderuje drzewo przechowywane w pamięci. Symuluje aktualizację przeprowadzaną przez Reacta na korzeniu drzewa. Jeśli nowy element ma ten sam typ i klucz, co poprzedni, drzewo zostanie zaktualizowane; w przeciwnym wypadku drzewo zostanie odmontowane i zamontowane ponownie.
testRenderer.unmount()
testRenderer.unmount()
Odmontowuje drzewo przechowywane w pamięci, wywołując odpowiednie zdarzenia z cyklu życia komponentów.
testRenderer.getInstance()
testRenderer.getInstance()
Zwraca instancję korzenia drzewa, jeśli takowy istnieje. Nie zadziała, jeśli komponent główny jest funkcją, ponieważ funkcje nie mają własnych instancji.
testRenderer.root
testRenderer.root
Zwraca “instancję testową” korzenia drzewa. Przydatne do wykonywania asercji na poszczególnych węzłach drzewa, a także do wyszukiwania innych “instancji testowych” w poddrzewach.
testInstance.find()
testInstance.find(test)
Wyszukuje w poddrzewie dokładnie jedną instancję testową, dla której wywołanie test(testInstance)
zwróci true
. Jeśli funkcja test(testInstance)
nie zwróci true
dla dokładnie jednej instancji, rzucony zostanie wyjątek.
testInstance.findByType()
testInstance.findByType(type)
Wyszukuje w poddrzewie dokładnie jedną instancję testową o podanym typie type
. Jeśli funkcja znajdzie inną liczbę instancji, rzucony zostanie wyjątek.
testInstance.findByProps()
testInstance.findByProps(props)
Wyszukuje w poddrzewie dokładnie jedną instancję testową o podanych właściwościach props
. Jeśli funkcja znajdzie inną liczbę instancji, rzucony zostanie wyjątek.
testInstance.findAll()
testInstance.findAll(test)
Wyszukuje w poddrzewie wszystkie instancje testowe, dla których funkcja test(testInstance)
zwraca true
.
testInstance.findAllByType()
testInstance.findAllByType(type)
Wyszukuje w poddrzewie wszystkie instancje testowe o podanym typie type
.
testInstance.findAllByProps()
testInstance.findAllByProps(props)
Wyszukuje w poddrzewie wszystkie instancje testowe o podanych właściwościach props
.
testInstance.instance
testInstance.instance
Zwraca instancję komponentu powiązanego z daną instancją testową. Działa tylko dla komponentów klasowych, ponieważ funkcyjne nie mają instancji. Wynik jest referencją odpowiadającą this
w danym komponencie.
testInstance.type
testInstance.type
Zwraca typ komponentu powiązanego z daną instancją testową. Przykładowo, typem komponentu <Button />
jest Button
.
testInstance.props
testInstance.props
Zwraca atrybuty powiązane z daną instancją testową. Przykładowo, właściwościami komponentu <Button size="small" />
są: {size: 'small'}
.
testInstance.parent
testInstance.parent
Zwraca instancję rodzica dla danej instancji testowej.
testInstance.children
testInstance.children
Zwraca instancje potomków dla danej “instancji testowej”.
Pomysły
Do metody TestRenderer.create
jako argument można przekazać funkcję createNodeMock
, która pozwala na tworzenie własnych atrap referencji (ang. mock refs).
createNodeMock
jako argument przyjmuje element, a zwraca obiekt będący atrapą referencji.
Przydaje się to w testach komponentów, które korzystają z referencji (ang. refs) do innych komponentów.
import TestRenderer from 'react-test-renderer';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.input = null;
}
componentDidMount() {
this.input.focus();
}
render() {
return <input type="text" ref={el => this.input = el} />
}
}
let focused = false;
TestRenderer.create(
<MyComponent />,
{
createNodeMock: (element) => {
if (element.type === 'input') {
// atrapa funkcji "focus"
return {
focus: () => {
focused = true;
}
};
}
return null;
}
}
);
expect(focused).toBe(true);