@@ -76,17 +76,18 @@ facilitate testing implementation details). Read more about this in
76
76
77
77
* [ Installation] ( #installation )
78
78
* [ Usage] ( #usage )
79
- * [ ` Simulate ` ] ( #simulate )
80
- * [ ` flushPromises ` ] ( #flushpromises )
81
- * [ ` waitForExpect ` ] ( #waitforexpect )
82
79
* [ ` render ` ] ( #render )
80
+ * [ ` Simulate ` ] ( #simulate )
81
+ * [ ` wait ` ] ( #wait )
83
82
* [ Custom Jest Matchers] ( #custom-jest-matchers )
84
83
* [ ` toBeInTheDOM ` ] ( #tobeinthedom )
85
84
* [ ` toHaveTextContent ` ] ( #tohavetextcontent )
86
85
* [ ` TextMatch ` ] ( #textmatch )
87
86
* [ ` query ` APIs] ( #query-apis )
88
87
* [ Examples] ( #examples )
89
88
* [ FAQ] ( #faq )
89
+ * [ Deprecated APIs] ( #deprecated-apis )
90
+ * [ ` flushPromises ` ] ( #flushpromises )
90
91
* [ Other Solutions] ( #other-solutions )
91
92
* [ Guiding Principles] ( #guiding-principles )
92
93
* [ Contributors] ( #contributors )
@@ -110,8 +111,9 @@ This library has a `peerDependencies` listing for `react-dom`.
110
111
``` javascript
111
112
// __tests__/fetch.js
112
113
import React from ' react'
113
- import {render , Simulate , flushPromises } from ' react-testing-library'
114
- import axiosMock from ' axios'
114
+ import {render , Simulate , wait } from ' react-testing-library'
115
+ import ' react-testing-library/extend-expect' // this adds custom expect matchers
116
+ import axiosMock from ' axios' // the mock lives in a __mocks__ directory
115
117
import Fetch from ' ../fetch' // see the tests for a full implementation
116
118
117
119
test (' Fetch makes an API call and displays the greeting when load-greeting is clicked' , async () => {
@@ -128,61 +130,18 @@ test('Fetch makes an API call and displays the greeting when load-greeting is cl
128
130
Simulate .click (getByText (' Load Greeting' ))
129
131
130
132
// let's wait for our mocked `get` request promise to resolve
131
- await flushPromises ()
133
+ // wait will wait until the callback doesn't throw an error
134
+ await wait (() => getByTestId (' greeting-text' ))
132
135
133
136
// Assert
134
137
expect (axiosMock .get ).toHaveBeenCalledTimes (1 )
135
138
expect (axiosMock .get ).toHaveBeenCalledWith (url)
136
- expect (getByTestId (' greeting-text' ).textContent ).toBe (' hello there' )
139
+ expect (getByTestId (' greeting-text' )).toHaveTextContent (' hello there' )
140
+ // snapshots work great with regular DOM nodes!
137
141
expect (container .firstChild ).toMatchSnapshot ()
138
142
})
139
143
```
140
144
141
- ### ` Simulate `
142
-
143
- This is simply a re-export from the ` Simulate ` utility from
144
- ` react-dom/test-utils ` . See [ the docs] ( https://reactjs.org/docs/test-utils.html#simulate ) .
145
-
146
- ### ` flushPromises `
147
-
148
- This is a simple utility that's useful for when your component is doing some
149
- async work that you've mocked out, but you still need to wait until the next
150
- tick of the event loop before you can continue your assertions. It simply
151
- returns a promise that resolves in a ` setImmediate ` . Especially useful when
152
- you make your test function an ` async ` function and use
153
- ` await flushPromises() ` .
154
-
155
- See an example in the section about ` render ` below.
156
-
157
- ### ` waitForExpect `
158
-
159
- Defined as:
160
-
161
- ``` javascript
162
- waitForExpect (expectation : () => void , timeout?: number, interval?: number) => Promise < {}> ;
163
- ```
164
-
165
- When in need to wait for non-deterministic periods of time you can use waitForExpect,
166
- to wait for your expectations to pass. Take a look at [ ` Is there a different way to wait for things to happen? ` ] ( #waitForExpect ) part of the FAQ,
167
- or the function documentation here: [ ` wait-for-expect ` ] ( https://github.com/TheBrainFamily/wait-for-expect )
168
- or just take a look at this simple example:
169
-
170
- ``` javascript
171
- ...
172
- await waitForExpect (() => expect (queryByLabelText (' username' )).not .toBeNull ())
173
- getByLabelText (' username' ).value = ' chucknorris'
174
- ...
175
- ```
176
-
177
- Another advantage of waitForExpect in comparison to flushPromises, is that
178
- flushPromises will not flush promises that have not been queued up already,
179
- for example, if they will queue up as a result of the initial promises.
180
- In consequence of that, you might have to call flushPromises multiple times to get your components
181
- to your desired state.
182
-
183
- This can happen for example, when you integration test your apollo-connected react components
184
- that go a couple level deep, with queries fired up in consequent components.
185
-
186
145
### ` render `
187
146
188
147
In the example above, the ` render ` method returns an object that has a few
@@ -283,6 +242,44 @@ const usernameInputElement = getByTestId('username-input')
283
242
> Learn more about ` data-testid ` s from the blog post
284
243
> [ "Making your UI tests resilient to change"] [ data-testid-blog-post ]
285
244
245
+ ### ` Simulate `
246
+
247
+ This is simply a re-export from the ` Simulate ` utility from
248
+ ` react-dom/test-utils ` . See [ the docs] ( https://reactjs.org/docs/test-utils.html#simulate ) .
249
+
250
+ ### ` wait `
251
+
252
+ Defined as:
253
+
254
+ ``` typescript
255
+ function wait(
256
+ callback ? : () => void ,
257
+ options ? : {
258
+ timeout? : number
259
+ interval? : number
260
+ },
261
+ ): Promise <void >
262
+ ```
263
+
264
+ When in need to wait for non - deterministic periods of time you can use ` wait ` ,
265
+ to wait for your expectations to pass . The ` wait ` function is a small wrapper
266
+ around the
267
+ [`wait-for-expect`](https : // github.com/TheBrainFamily/wait-for-expect) module.
268
+ Here ' s a simple example:
269
+
270
+ ` ` ` javascript
271
+ // ...
272
+ // wait until the callback does not throw an error. In this case, that means
273
+ // it'll wait until we can get a form control with a label that matches "username"
274
+ await wait(() => getByLabelText('username'))
275
+ getByLabelText('username').value = 'chucknorris'
276
+ // ...
277
+ ` ` `
278
+
279
+ This can be useful when (for example ) you integration test your apollo -connected
280
+ react components that go a couple level deep , with queries fired up in
281
+ consequent components.
282
+
286
283
## Custom Jest Matchers
287
284
288
285
There are two simple API which extend the ` expect ` API of jest for making assertions easier.
@@ -600,60 +597,26 @@ react components.
600
597
601
598
</details >
602
599
603
- <details >
604
-
605
- <summary >How does flushPromises work and why would I need it?</summary >
606
-
607
- As mentioned [ before] ( #flushpromises ) , ` flushPromises ` uses
608
- [ ` setImmediate ` ] [ set-immediate ] to schedule resolving a promise after any pending
609
- tasks in
610
- [ the message queue] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop )
611
- are processed. This includes any promises fired before in your test.
600
+ ## Deprecated APIs
612
601
613
- If there are promise callbacks already in JavaScript's message queue pending to be
614
- processed at the time ` flushPromises ` is called, then these will be processed before
615
- the promise returned by ` flushPromises ` is resolved. So when you
616
- ` await flushPromises() ` the code immediately after it is guaranteed to occur after
617
- all the side effects of your async requests have ocurred. This includes any data
618
- your test components might have requested.
619
-
620
- This is useful for instance, if your components perform any data requests and update
621
- their state with the results when the request is resolved. It's important to note
622
- that this is only effective if you've mocked out your async requests to resolve
623
- immediately (like the ` axios ` mock we have in the examples). It will not ` await `
624
- for promises that are not already resolved by the time you attempt to flush them.
625
-
626
- In case this doesn't work for you the way you would expect, take a look at the
627
- waitForExpect function that should be much more intuitive to use.
628
-
629
- </details >
630
-
631
- <details >
632
-
633
- <summary ><a name =" waitForExpectFAQ " ></a >Is there a different way to wait for things to happen? For example for end to end or contract tests?</summary >
634
- Definitely! There is an abstraction called ` waitForExpect ` that will keep
635
- calling your expectations until a timeout or the expectation passes - whatever happens first.
636
-
637
- Please take a look at this example (taken from [ ` here ` ] ( https://github.com/kentcdodds/react-testing-library/blob/master/src/__tests__/end-to-end.js ) ):
638
-
639
- ``` javascript
640
- import {render , waitForExpect } from ' react-testing-library'
641
- test (' it waits for the data to be loaded' , async () => {
642
- const {queryByText , queryByTestId } = render (< ComponentWithLoader / > )
643
-
644
- // Initially the loader shows
645
- expect (queryByText (' Loading...' )).toBeTruthy ()
646
-
647
- // This will pass when the state of the component changes once the data is available
648
- // the loader will disappear, and the data will be shown
649
- await waitForExpect (() => expect (queryByText (' Loading...' )).toBeNull ())
650
- expect (queryByTestId (' message' ).textContent ).toMatch (/ Hello World/ )
651
- })
652
- ```
602
+ ### ` flushPromises `
653
603
654
- For consistency and making your tests easier to understand, you can use it instead of flushPromises.
604
+ > This API was deprecated in favor of [` wait ` ](#wait ). We try to avoid having
605
+ > two ways to do the same thing and you can accomplish everything with `wait`
606
+ > that you could with `flushPromises`. A big advantage of `wait`, is that
607
+ > `flushPromises` will not flush promises that have not been queued up already,
608
+ > for example, if they will queue up as a result of the initial promises. In
609
+ > consequence of that, you might have to call `flushPromises` multiple times to
610
+ > get your components to your desired state. You can accomplish the exact same
611
+ > behavior with `wait` as you had with `flushPromises` by calling `wait` with
612
+ > no arguments: `await wait()`
655
613
656
- </details >
614
+ This is a simple utility that's useful for when your component is doing some
615
+ async work that you've mocked out, but you still need to wait until the next
616
+ tick of the event loop before you can continue your assertions. It simply
617
+ returns a promise that resolves in a `setImmediate`. Especially useful when
618
+ you make your test function an `async` function and use
619
+ `await flushPromises()`.
657
620
658
621
## Other Solutions
659
622
0 commit comments