Thanks to visit codestin.com
Credit goes to pl.legacy.reactjs.org

We want to hear from you!Take our 2021 Community Survey!
Ta witryna nie jest już aktualizowana.Przejdź do react.dev

Narzędzia do testowania

Importowanie

import ReactTestUtils from 'react-dom/test-utils'; // ES6
var ReactTestUtils = require('react-dom/test-utils'); // ES5 z zainstalowanym npm

Ogólne informacje

ReactTestUtils pozwala na łatwiejsze testowanie komponentów reactowych przy pomocy dowolnego frameworka. W Facebooku korzystamy do tego celu z biblioteki Jest, która sprawia, że pisanie testów jest mniej kłopotliwe. Do nauki podstaw Jesta polecamy samouczek dla Reacta, znajdujący się na oficjalnej stronie biblioteki.

Uwaga:

Zalecamy korzystanie z biblioteki React Testing Library. Została ona stworzona w celu propagowania idei pisania testów, które używają komponentów podobnie jak potencjalny użytkownik aplikacji.

Dla Reacta w wersji 16 lub niższej polecamy bibliotekę Enzyme, dzięki której w łatwy sposób można pisać asercje, a także zmieniać i przechodzić drzewo zwrócone przez komponenty reactowe.

Dokumentacja

act()

Aby przygotować dany komponent do testowania, należy renderujący i aktualizujący go kod “opakować” w wywołanie funkcji act(). Dzięki temu test zostanie uruchomiony w taki sposób, aby jak najwierniej odtworzyć zachowanie Reacta w przeglądarce.

Uwaga

Biblioteka react-test-renderer również udostępnia funkcję act, która działa w podobny sposób.

Dla przykładu, załóżmy, że napisaliśmy następujący komponent Counter (pol. licznik):

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 0};
    this.handleClick = this.handleClick.bind(this);
  }
  componentDidMount() {
    document.title = `Kliknięto ${this.state.count} razy`;
  }
  componentDidUpdate() {
    document.title = `Kliknięto ${this.state.count} razy`;
  }
  handleClick() {
    this.setState(state => ({
      count: state.count + 1,
    }));
  }
  render() {
    return (
      <div>
        <p>Kliknięto {this.state.count} razy</p>
        <button onClick={this.handleClick}>
          Kliknij mnie
        </button>
      </div>
    );
  }
}

W taki oto sposób moglibyśmy go przetestować:

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('potrafi wyrenderować i aktualizować licznik', () => {
  // Testuje pierwsze renderowanie i metodę cyklu życia "componentDidMount"
  act(() => {    ReactDOM.createRoot(container).render(<Counter />);  });  const button = container.querySelector('button');
  const label = container.querySelector('p');
  expect(label.textContent).toBe('Kliknięto 0 razy');
  expect(document.title).toBe('Kliknięto 0 razy');

  // Testuje drugie renderowanie i metodę cyklu życia "componentDidUpdate"
  act(() => {    button.dispatchEvent(new MouseEvent('click', {bubbles: true}));  });  expect(label.textContent).toBe('Kliknięto 1 razy');
  expect(document.title).toBe('Kliknięto 1 razy');
});

Zwróć uwagę, że przesyłanie zdarzeń DOM działa tylko wtedy, gdy kontener jest umieszczony w document. Aby uniknąć powtarzania szablonowego kodu, możesz użyć biblioteki pomocniczej, jak na przykład React Testing Library.

W przykładach znajdziesz więcej szczegółów na temat zachowania funkcji act(), jak również przykłady jej użycia.


mockComponent()

mockComponent(
  componentClass,
  [mockTagName]
)

Jeśli przekażesz do tej funkcji atrapę komponentu (ang. mocked component), zostanie ona wzbogacona o przydatne funkcje, które pozwolą na traktowanie jej jak sztucznego komponentu reactowego. Zamiast wyrenderować się zgodnie z implementacją, komponent stanie się zwykłym elementem <div> (lub innym, jeśli podamy wartość w parametrze mockTagName) renderującym przekazanych potomków.

Uwaga:

Funkcja mockComponent() jest przestarzała. Zamiast niej zalecamy używanie funkcji jest.mock().


isElement()

isElement(element)

Zwraca true, jeśli argument element jest elementem reactowym.


isElementOfType()

isElementOfType(
  element,
  componentClass
)

Zwraca true, jeśli argument element jest elementem reactowym o klasie podanej jako componentClass.


isDOMComponent()

isDOMComponent(instance)

Zwraca true, jeśli argument instance jest standardowym komponentem DOM (np. <div> lub <span>).


isCompositeComponent()

isCompositeComponent(instance)

Zwraca true, jeśli argument instance jest komponentem użytkownika, typu klasowego lub funkcyjnego.


isCompositeComponentWithType()

isCompositeComponentWithType(
  instance,
  componentClass
)

Zwraca true, jeśli argument instance jest komponentem o klasie podanej jako componentClass.


findAllInRenderedTree()

findAllInRenderedTree(
  tree,
  test
)

Przeszukuje wszystkie komponenty w drzewie tree i zwraca te, dla których wywołanie funkcji test(komponent) daje true. Funkcja ta sama w sobie nie jest zbyt użyteczna, jednak jest podstawą dla innych narzędzi do testowania.


scryRenderedDOMComponentsWithClass()

scryRenderedDOMComponentsWithClass(
  tree,
  className
)

Wyszukuje wszystkie elementy DOM w wyrenderowanym drzewie, których nazwa klasy CSS odpowiada wartości argumentu className.


findRenderedDOMComponentWithClass()

findRenderedDOMComponentWithClass(
  tree,
  className
)

Podobna w działaniu do scryRenderedDOMComponentsWithClass(), lecz oczekuje dokładnie jednego wyniku. W przypadku znalezienia innej liczby elementów rzuca wyjątek.


scryRenderedDOMComponentsWithTag()

scryRenderedDOMComponentsWithTag(
  tree,
  tagName
)

Wyszukuje wszystkie elementy DOM w wyrenderowanym drzewie, których nazwa znacznika pasuje do wartości argumentu tagName.


findRenderedDOMComponentWithTag()

findRenderedDOMComponentWithTag(
  tree,
  tagName
)

Podobna w działaniu do scryRenderedDOMComponentsWithTag(), lecz oczekuje dokładnie jednego wyniku. W przypadku znalezienia innej liczby elementów rzuca wyjątek.


scryRenderedComponentsWithType()

scryRenderedComponentsWithType(
  tree,
  componentClass
)

Wyszukuje wszystkie instancje komponentów, których typ jest równy argumentowi componentClass.


findRenderedComponentWithType()

findRenderedComponentWithType(
  tree,
  componentClass
)

Podobna w działaniu do scryRenderedComponentsWithType(), lecz oczekuje dokładnie jednego wyniku. W przypadku znalezienia innej liczby elementów rzuca wyjątek.


renderIntoDocument()

renderIntoDocument(element)

Renderuje element reactowy do stworzonego w locie węzła drzewa DOM. Ta funkcja działa tylko na drzewie DOM w ramach dokumentu. Daje ten sam rezultat, co:

const domContainer = document.createElement('div');
ReactDOM.createRoot(domContainer).render(element);

Uwaga:

Zanim zaimportujesz bibliotekę React w kodzie, w globalnym zakresie muszą być dostępne zmienne window, window.document oraz window.document.createElement. W przeciwnym wypadku React będzie “myślał”, że nie ma dostępu do drzewa DOM, co spowoduje wyłączenie niektórych funkcji, np. setState.


Inne narzędzia

Simulate

Simulate.{eventName}(
  element,
  [eventData]
)

Symuluje przesłanie zdarzenia do węzła DOM, opcjonalnie dodając do niego dane zawarte w argumencie eventData.

Obiekt Simulate posiada odpowiednie metody dla każdego ze zdarzeń obsługiwanego przez Reacta.

Kliknięcie w element

// <button ref={(node) => this.button = node}>...</button>
const node = this.button;
ReactTestUtils.Simulate.click(node);

Zmiana wartości pola i wciśnięcie klawisza ENTER.

// <input ref={(node) => this.textInput = node} />
const node = this.textInput;
node.value = 'żyrafa';
ReactTestUtils.Simulate.change(node);
ReactTestUtils.Simulate.keyDown(node, {key: "Enter", keyCode: 13, which: 13});

Uwaga

Wszelkie właściwości dla zdarzenia (np. keyCode, which itp.) należy przekazać jawnie, ponieważ React nie dodaje ich automatycznie.


Is this page useful?Edytuj tę stronę