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 (#17)
**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
347
for a full example of this.
217
348
218
-
**If I can't use shallow rendering, how do I mock out components in tests?**
349
+
</details>
350
+
351
+
<details>
352
+
353
+
<summary>If I can't use shallow rendering, how do I mock out components in tests?</summary>
219
354
220
355
In general, you should avoid mocking out components (see
221
356
[the Guiding Principles section](#guiding-principles)). However if you need to,
@@ -265,15 +400,23 @@ something more
265
400
Learn more about how Jest mocks work from my blog post:
266
401
["But really, what is a JavaScript mock?"](https://blog.kentcdodds.com/but-really-what-is-a-javascript-mock-10d060966f7d)
267
402
268
-
**What if I want to verify that an element does NOT exist?**
403
+
</details>
404
+
405
+
<details>
406
+
407
+
<summary>What if I want to verify that an element does NOT exist?</summary>
269
408
270
409
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?**
444
+
</details>
445
+
446
+
<details>
447
+
448
+
<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
449
303
450
You can make your selector just choose the one you want by including :nth-child in the selector.
304
451
@@ -322,8 +469,12 @@ const {getByTestId} = render(/* your component with the items */)
322
469
constthirdItem=getByTestId(`item-${items[2].id}`)
323
470
```
324
471
325
-
**What about enzyme is "bloated with complexity and features" and "encourage poor testing
326
-
practices"?**
472
+
</details>
473
+
474
+
<details>
475
+
476
+
<summary>What about enzyme is "bloated with complexity and features" and "encourage
477
+
poor testing practices"?</summary>
327
478
328
479
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)
488
+
> The more your tests resemble the way your software is used, the more confidence they can give you. - [17 Feb 2018][guiding-principle]
338
489
339
490
Because users can't directly interact with your app's component instances,
340
491
assert on their internal state or what components they render, or call their
@@ -345,7 +496,11 @@ That's not to say that there's never a use case for doing those things, so they
345
496
should be possible to accomplish, just not the default and natural way to test
346
497
react components.
347
498
348
-
**How does `flushPromises` work and why would I need it?**
499
+
</details>
500
+
501
+
<details>
502
+
503
+
<summary>How does flushPromises work and why would I need it?</summary>
349
504
350
505
As mentioned [before](#flushpromises), `flushPromises` uses
351
506
[`setImmediate`][set-immediate] to schedule resolving a promise after any pending
@@ -366,6 +521,8 @@ that this is only effective if you've mocked out your async requests to resolve
366
521
immediately (like the `axios` mock we have in the examples). It will not `await`
367
522
for promises that are not already resolved by the time you attempt to flush them.
368
523
524
+
</details>
525
+
369
526
## Other Solutions
370
527
371
528
In preparing this project,
@@ -378,7 +535,7 @@ this one instead.
378
535
379
536
## Guiding Principles
380
537
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)
538
+
> [The more your tests resemble the way your software is used, the more confidence they can give you.][guiding-principle]
382
539
383
540
We try to only expose methods and utilities that encourage you to write tests
384
541
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