Jak sprawdzić, czy element nie istnieje, używając żartu i biblioteki-testu-reagowania?

102

Mam bibliotekę komponentów, którą piszę testy jednostkowe do używania Jest i bibliotekę reagowania. Na podstawie niektórych rekwizytów lub wydarzeń chcę sprawdzić, czy określone elementy nie są renderowane.

getByText, getByTestIditp. zgłoszenie i błąd, react-testing-libraryjeśli element nie zostanie znaleziony, co powoduje niepowodzenie testu przed uruchomieniem expectfunkcji.

Jak przetestować coś, co nie istnieje w żartach, korzystając z biblioteki React-testing?

SomethingOn
źródło

Odpowiedzi:

215

Z dokumentów DOM Testing-library - wygląd i znikanie

Nie ma elementów potwierdzających

Standardowe getBymetody generują błąd, gdy nie mogą znaleźć elementu, więc jeśli chcesz stwierdzić, że elementu nie ma w DOM, możesz queryByzamiast tego użyć interfejsów API:

const submitButton = screen.queryByText('submit')
expect(submitButton).toBeNull() // it doesn't exist

Wersja queryAllAPI zwraca tablicę pasujących węzłów. Długość tablicy może być przydatna do potwierdzeń po dodaniu lub usunięciu elementów z DOM.

const submitButtons = screen.queryAllByText('submit')
expect(submitButtons).toHaveLength(2) // expect 2 elements

not.toBeInTheDocument

jest-domBiblioteka Narzędzie zapewnia .toBeInTheDocument()matcher, który może być wykorzystywany do stwierdzenia, że element jest w treści dokumentu, czy też nie. Może to być bardziej znaczące niż potwierdzenie wyniku zapytania null.

import '@testing-library/jest-dom/extend-expect'
// use `queryBy` to avoid throwing an error with `getBy`
const submitButton = screen.queryByText('submit')
expect(submitButton).not.toBeInTheDocument()
kentcdodds
źródło
4
Moje złe kentcdodds, dziękuję. Użyłem getByTestIdi otrzymałem ten sam błąd. Przepraszam, nie sprawdziłem FAQ. Świetna biblioteka! Czy możesz zmodyfikować swoją odpowiedź, aby zawierała `.toBeNull ();
Coś
3
Wydaje
2
Nowa witryna z dokumentami została opublikowana kilka dni temu. Powinienem był użyć bardziej trwałego łącza. Dzięki za aktualizację @pbre!
kentcdodds
1
Kolejny przydatny zasób: testing-library.com/docs/react-testing-library/cheatsheet
SomethingOn
6
a queryByTextdla tych, którzy chcą, aby odpowiednik getByTexttego był zerowy
S ..
24

Użyj queryBy/ queryAllBy.

Jak mówisz, getBy*i getAllBy*wyrzuć błąd, jeśli nic nie zostanie znalezione.

Jednak równoważne metody queryBy*i queryAllBy*zamiast tego zwracają nulllub []:

zapytanie wg

queryBy*zapytania zwracają pierwszy pasujący węzeł dla zapytania i zwracają, nulljeśli żadne elementy nie są zgodne. Jest to przydatne do potwierdzania elementu, którego nie ma. Jest to generowane, jeśli zostanie znalezionych więcej niż jedno dopasowanie (zamiast tego użyj queryAllBy).

queryAllBy*Zapytania queryAllBy zwracają tablicę wszystkich pasujących węzłów dla zapytania i zwracają pustą tablicę ( []), jeśli żadne elementy nie są zgodne.

https://testing-library.com/docs/dom-testing-library/api-queries#queryby

Tak więc w przypadku dwóch wymienionych, zamiast tego używałbyś queryByTexti queryByTestId, ale działają one dla wszystkich zapytań, a nie tylko tych dwóch.

Sam
źródło
2
To o wiele lepsze niż zaakceptowana odpowiedź. Czy ten interfejs API jest nowszy?
RubbelDieKatz
1
Dzięki za miłe słowa! Jest to w zasadzie ta sama funkcjonalność, co zaakceptowana odpowiedź , więc nie sądzę, że jest to nowszy interfejs API (ale mogę się mylić). Jedyną prawdziwą różnicą między tą odpowiedzią a akceptowaną jest to, że zaakceptowana odpowiedź mówi, że istnieje tylko metoda, która robi this ( queryByTestId), podczas gdy w rzeczywistości istnieją dwa całe zestawy metod, z których queryByTestIdjeden jest konkretnym przykładem.
Sam,
Dzięki, o wiele wolałbym to niż ustawianie identyfikatorów
testowych
14

Musisz użyć queryByTestId zamiast getByTestId.

Oto przykład kodu, w którym chcę sprawdzić, czy komponent o identyfikatorze „samochód” nie istnieje.

 describe('And there is no car', () => {
  it('Should not display car mark', () => {
    const props = {
      ...defaultProps,
      base: null,
    }
    const { queryByTestId } = render(
      <IntlProvider locale="fr" messages={fr}>
        <CarContainer{...props} />
      </IntlProvider>,
    );
    expect(queryByTestId(/car/)).toBeNull();
  });
});
Valentin Garreau
źródło
7

getBy * zgłasza błąd, gdy nie znajduje elementów, więc możesz to sprawdzić

expect(() => getByText('your text')).toThrow('Unable to find an element');
Gabriel Vasile
źródło
Może to być dość podatne na błędy. Zgłoszenia błędów są używane do celów debugowania, a nie do weryfikacji.
Milen Gardev
2

Możesz skorzystać z biblioteki react-native-testing-library „getAllByType”, a następnie sprawdzić, czy składnik jest pusty. Ma tę zaletę, że nie musi ustawiać TestID, powinien również działać z komponentami innych firm

 it('should contain Customer component', () => {
    const component = render(<Details/>);
    const customerComponent = component.getAllByType(Customer);
    expect(customerComponent).not.toBeNull();
  });
Andy Rich
źródło
Ten rodzaj narusza przesłankę braku szczegółów implementacji (takich jak nazwa komponentu) w teście.
RubbelDieKatz