You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(render): add new query capabilities for improved tests
**What**: Add the following methods
- queryByText
- getByText
- queryByPlaceholderText
- getByPlaceholderText
- queryByLabelText
- getByLabelText
**Why**: Closes#16
These will really improve the usability of this module. These also align much better with the guiding principles 👍
**How**:
- Created a `queries.js` file where we have all the logic for the queries and their associated getter functions
- Migrate tests where it makes sense
- Update docs considerably.
**Checklist**:
* [x] Documentation
* [x] Tests
* [x] Ready to be merged <!-- In your opinion, is this ready to be merged as soon as it's reviewed? -->
* [ ] Added myself to contributors table N/A
[Open the tests](https://github.com/kentcdodds/react-testing-library/blob/master/src/__tests__/number-display.js)
216
331
for a full example of this.
217
332
218
-
**If I can't use shallow rendering, how do I mock out components in tests?**
333
+
</details>
334
+
335
+
<details>
336
+
337
+
<summary>If I can't use shallow rendering, how do I mock out components in tests?</summary>
219
338
220
339
In general, you should avoid mocking out components (see
221
340
[the Guiding Principles section](#guiding-principles)). However if you need to,
@@ -265,15 +384,23 @@ something more
265
384
Learn more about how Jest mocks work from my blog post:
266
385
["But really, what is a JavaScript mock?"](https://blog.kentcdodds.com/but-really-what-is-a-javascript-mock-10d060966f7d)
267
386
268
-
**What if I want to verify that an element does NOT exist?**
387
+
</details>
388
+
389
+
<details>
390
+
391
+
<summary>What if I want to verify that an element does NOT exist?</summary>
269
392
270
393
You typically will get access to rendered elements using the `getByTestId` utility. However, that function will throw an error if the element isn't found. If you want to specifically test for the absence of an element, then you should use the `queryByTestId` utility which will return the element if found or `null` if not.
**What if I’m iterating over a list of items that I want to put the data-testid="item" attribute on. How do I distinguish them from each other?**
428
+
</details>
429
+
430
+
<details>
431
+
432
+
<summary>What if I’m iterating over a list of items that I want to put the data-testid="item" attribute on. How do I distinguish them from each other?</summary>
302
433
303
434
You can make your selector just choose the one you want by including :nth-child in the selector.
304
435
@@ -322,8 +453,12 @@ const {getByTestId} = render(/* your component with the items */)
322
453
constthirdItem=getByTestId(`item-${items[2].id}`)
323
454
```
324
455
325
-
**What about enzyme is "bloated with complexity and features" and "encourage poor testing
326
-
practices"?**
456
+
</details>
457
+
458
+
<details>
459
+
460
+
<summary>What about enzyme is "bloated with complexity and features" and "encourage
461
+
poor testing practices"?</summary>
327
462
328
463
Most of the damaging features have to do with encouraging testing implementation
> The less your tests resemble the way your software is used, the less confidence they can give you. - [17 Feb 2018](https://twitter.com/kentcdodds/status/965052178267176960)
472
+
> The more your tests resemble the way your software is used, the more confidence they can give you. - [17 Feb 2018][guiding-principle]
338
473
339
474
Because users can't directly interact with your app's component instances,
340
475
assert on their internal state or what components they render, or call their
@@ -345,7 +480,11 @@ That's not to say that there's never a use case for doing those things, so they
345
480
should be possible to accomplish, just not the default and natural way to test
346
481
react components.
347
482
348
-
**How does `flushPromises` work and why would I need it?**
483
+
</details>
484
+
485
+
<details>
486
+
487
+
<summary>How does flushPromises work and why would I need it?</summary>
349
488
350
489
As mentioned [before](#flushpromises), `flushPromises` uses
351
490
[`setImmediate`][set-immediate] to schedule resolving a promise after any pending
@@ -366,6 +505,8 @@ that this is only effective if you've mocked out your async requests to resolve
366
505
immediately (like the `axios` mock we have in the examples). It will not `await`
367
506
for promises that are not already resolved by the time you attempt to flush them.
368
507
508
+
</details>
509
+
369
510
## Other Solutions
370
511
371
512
In preparing this project,
@@ -378,7 +519,7 @@ this one instead.
378
519
379
520
## Guiding Principles
380
521
381
-
> [The less your tests resemble the way your software is used, the less confidence they can give you.](https://twitter.com/kentcdodds/status/965052178267176960)
522
+
> [The more your tests resemble the way your software is used, the more confidence they can give you.][guiding-principle]
382
523
383
524
We try to only expose methods and utilities that encourage you to write tests
384
525
that closely resemble how your react components are used.
exports[`getByTestId finds matching element 1`] =`
4
-
<span
5
-
data-testid="test-component"
6
-
/>
7
-
`;
8
-
9
-
exports[`getByTestId throws error when no matching element exists 1`] =`"Unable to find element by [data-testid=\\"unknown-data-testid\\"]"`;
10
-
11
-
exports[`queryByTestId finds matching element 1`] =`
12
-
<span
13
-
data-testid="test-component"
14
-
/>
15
-
`;
3
+
exports[`get throws a useful error message 1`] =`"Unable to find a label with the text of: LucyRicardo"`;
4
+
5
+
exports[`get throws a useful error message 2`] =`"Unable to find an element with the placeholder text of: LucyRicardo"`;
6
+
7
+
exports[`get throws a useful error message 3`] =`"Unable to find an element with the text: LucyRicardo. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible."`;
8
+
9
+
exports[`get throws a useful error message 4`] =`"Unable to find an element by: [data-testid=\\"LucyRicardo\\"]"`;
10
+
11
+
exports[`label with no form control 1`] =`"Found a label with the text of: alone, however no form control was found associated to that label. Make sure you're using the \\"for\\" attribute or \\"aria-labelledby\\" attribute correctly."`;
12
+
13
+
exports[`totally empty label 1`] =`"Found a label with the text of: , however no form control was found associated to that label. Make sure you're using the \\"for\\" attribute or \\"aria-labelledby\\" attribute correctly."`;
0 commit comments