Wie testest du die Nichtexistenz eines Elements mit einer Scherz- und Reaktionstestbibliothek?

95

Ich habe eine Komponentenbibliothek, in der ich Unit-Tests für die Verwendung von Jest und React-Testing-Library schreibe. Basierend auf bestimmten Requisiten oder Ereignissen möchte ich überprüfen, ob bestimmte Elemente nicht gerendert werden.

getByText, getByTestIdUsw. throw und Fehler in , react-testing-librarywenn das Element nicht gefunden wird , um den Test zu verursachen , bevor die zum Scheitern verurteilt expectFunktion ausgelöst wird .

Wie testest du mit der React-Testing-Bibliothek auf etwas, das nicht im Scherz existiert?

Etwas auf
quelle

Antworten:

201

Aus DOM-Testbibliotheksdokumenten - Aussehen und Verschwinden

Durchsetzungselemente sind nicht vorhanden

Die Standardmethoden geben getByeinen Fehler aus, wenn sie kein Element finden können. Wenn Sie also behaupten möchten, dass ein Element nicht im DOM vorhanden ist, können Sie queryBystattdessen APIs verwenden:

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

Die queryAllAPI-Version gibt ein Array übereinstimmender Knoten zurück. Die Länge des Arrays kann für Zusicherungen nützlich sein, nachdem Elemente zum DOM hinzugefügt oder daraus entfernt wurden.

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

not.toBeInTheDocument

Die jest-domDienstprogrammbibliothek stellt den .toBeInTheDocument()Matcher bereit , mit dem festgestellt werden kann, ob sich ein Element im Hauptteil des Dokuments befindet oder nicht. Dies kann sinnvoller sein als die Behauptung eines Abfrageergebnisses 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
quelle
4
Meine schlechten Kentcdodds, danke. Ich getByTestIdhabe den gleichen Fehler verwendet und bekommen. Und ich habe die FAQ leider nicht überprüft. Tolle Bibliothek! Können Sie Ihre Antwort so ändern, dass sie `.toBeNull () enthält?
Etwas
3
Ich glaube, der obige Link sollte auf die Dokumente der
React
2
Die neue Dokumentenseite wurde vor einigen Tagen veröffentlicht. Ich hätte einen dauerhafteren Link verwenden sollen. Danke für das Update @pbre!
Kentcdodds
1
Eine weitere nützliche Ressource: testing-library.com/docs/react-testing-library/cheatsheet
SomethingOn
6
und queryByTextfür diejenigen, die das Äquivalent dazu wollen getByText, ist null sicher
S ..
22

Verwenden Sie queryBy/ queryAllBy.

Wie Sie sagen, getBy*und getAllBy*werfen Sie einen Fehler, wenn nichts gefunden wird.

Jedoch ist die äquivalenten Verfahren queryBy*und queryAllBy*zurück statt nulloder []:

queryBy

queryBy*Abfragen geben den ersten übereinstimmenden Knoten für eine Abfrage zurück und geben zurück, nullwenn keine Elemente übereinstimmen. Dies ist nützlich, um ein Element zu bestätigen, das nicht vorhanden ist. Dies wird ausgelöst, wenn mehr als eine Übereinstimmung gefunden wird (verwenden Sie stattdessen queryAllBy).

queryAllBy- queryAllBy* Abfragen geben ein Array aller übereinstimmenden Knoten für eine Abfrage zurück und ein leeres Array ( []), wenn keine Elemente übereinstimmen.

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

Für die beiden spezifischen, die Sie erwähnt haben, würden Sie stattdessen queryByTextund verwenden queryByTestId, aber diese funktionieren für alle Abfragen, nicht nur für diese beiden.

Sam
quelle
2
Dies ist viel besser als die akzeptierte Antwort. Ist diese API neuer?
RubbelDieKatz
1
Danke für die netten Worte! Dies ist im Grunde die gleiche Funktionalität wie die akzeptierte Antwort , daher denke ich nicht, dass es sich um eine neuere API handelt (aber ich könnte mich irren). Der einzige wirkliche Unterschied zwischen dieser und der akzeptierten Antwort besteht darin, dass die akzeptierte Antwort besagt, dass es nur eine Methode gibt, die dies tut ( queryByTestId), obwohl es tatsächlich zwei ganze Sätze von Methoden gibt, von denen queryByTestIdein spezifisches Beispiel ist.
Sam
Vielen Dank, ich würde dies viel lieber
tun,
13

Sie müssen queryByTestId anstelle von getByTestId verwenden.

Hier ein Codebeispiel, in dem ich testen möchte, ob die Komponente mit der ID "Auto" nicht vorhanden ist.

 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
quelle
4

getBy * gibt einen Fehler aus, wenn keine Elemente gefunden werden, sodass Sie dies überprüfen können

expect(() => getByText('your text')).toThrow('Unable to find an element');
Gabriel Vasile
quelle
0

Sie können die reaktionsnative Testbibliothek "getAllByType" verwenden und dann überprüfen, ob die Komponente null ist. Hat den Vorteil, dass TestID nicht eingestellt werden muss, sollte auch mit Komponenten von Drittanbietern funktionieren

 it('should contain Customer component', () => {
    const component = render(<Details/>);
    const customerComponent = component.getAllByType(Customer);
    expect(customerComponent).not.toBeNull();
  });
Andy Rich
quelle
Diese Art von Verstoß verstößt gegen die Prämisse, dass im Test keine Implementierungsdetails (z. B. der Komponentenname) enthalten sind.
RubbelDieKatz