The react-testing-library-cljs library provides a ClojureScript functions for the react-testing-library to simplify interop.
For more information about the principles and concepts behind the testing library, you can visit the official react-testing-library website.
The react-testing-library-cljs.screen namespace provides a wrapper around the react-testing-library's screen object, making it easier to interact with rendered components.
The react-testing-library-cljs.fire-event namespace simplifies firing events on rendered components, allowing you to simulate user interactions.
The react-testing-library-cljs.within namespace scopes queries to a specific element, useful when multiple similar elements exist in the DOM.
The react-testing-library-cljs.reagent.fire-event similar to the react-testing-library-cljs.fire-event, but calling reagent.core/flush after every event to trigger re-render.
The react-testing-library-cljs.reagent.render provides helper function to render reagent components.
Add the library to your project:
org.clojars.olecve/react-testing-library-cljs {:mvn/version "0.0.16"}
[org.clojars.olecve/react-testing-library-cljs "0.0.16"]
Install the npm dependency:
npm install --save-dev @testing-library/react
Add a :node-test build target:
;; shadow-cljs.edn
{:builds
{:test {:target :node-test
:output-to "out/test.js"}}}
Run tests with:
npx shadow-cljs compile test && node --require global-jsdom/register out/test.js
(ns my-app.core-test
(:require [cljs.test :refer [deftest is]]
[react-testing-library-cljs.reagent.render :as render]
[react-testing-library-cljs.screen :as screen]))
(defn greeting []
[:h1 "Hello, world!"])
(deftest renders-greeting
(render/render! [greeting])
(is (some? (screen/get-by-text "Hello, world!"))))
(ns my-app.events-test
(:require [cljs.test :refer [deftest is]]
[react-testing-library-cljs.reagent.render :as render]
[react-testing-library-cljs.reagent.fire-event :as fire-event]
[react-testing-library-cljs.screen :as screen]
[reagent.core :as r]))
(defn counter []
(let [count (r/atom 0)]
(fn []
[:button {:on-click #(swap! count inc)}
(str "Count: " @count)])))
(deftest click-increments-counter
(render/render! [counter])
(render/act #(fire-event/click (screen/get-by-text "Count: 0")))
(is (screen/get-by-text "Count: 1")))
(ns my-app.mocks-test
(:require [cljs.test :refer [deftest is]]
[react-testing-library-cljs.mocks :as mocks]
[react-testing-library-cljs.reagent.render :as render]
[react-testing-library-cljs.fire-event :as fire-event]
[react-testing-library-cljs.screen :as screen]))
(deftest tracks-button-click
(let [[calls on-click] (mocks/create)]
(render/render! [:button {:on-click on-click} "Submit"])
(fire-event/click (screen/get-by-text "Submit"))
(is (= 1 (count @calls)))))
withinUse within to scope queries to a subtree — useful when the same elements appear in multiple places:
(ns my-app.within-test
(:require [cljs.test :refer [deftest is]]
[react-testing-library-cljs.reagent.render :as render]
[react-testing-library-cljs.screen :as screen]
[react-testing-library-cljs.within :as within]))
(defn user-list []
[:ul
[:li {:role "listitem"} [:span "Alice"] [:button "Delete"]]
[:li {:role "listitem"} [:span "Bob"] [:button "Delete"]]])
(deftest deletes-correct-user
(render/render! [user-list])
(let [alice-item (first (screen/get-all-by-role "listitem"))]
(is (some? (within/get-by-text alice-item "Alice")))
(is (nil? (within/query-by-text alice-item "Bob")))))
find-by-* queries return a promise that resolves when a matching element appears (useful for async updates):
(ns my-app.async-test
(:require [cljs.test :refer [deftest async is]]
[react-testing-library-cljs.reagent.render :as render]
[react-testing-library-cljs.screen :as screen]))
(deftest finds-async-element
(async done
(render/render! [my-async-component])
(-> (screen/find-by-text "Loaded!")
(.then (fn [element]
(is (some? element))
(done))))))
Prerequisites:
~/.lein/profiles.clj:{:auth {:repository-auth {#"clojars" {:username "USERNAME" :password "CLOJARS_TOKEN"}}}}
Run:
bb release
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |