Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,180 --> 00:00:03,430
Now I wanna move on
2
00:00:03,430 --> 00:00:06,930
to a more complex scenario that we could test,
3
00:00:06,930 --> 00:00:09,630
a more complex component.
4
00:00:09,630 --> 00:00:12,840
I added this new async component,
5
00:00:12,840 --> 00:00:15,770
and you find that component also attached.
6
00:00:15,770 --> 00:00:19,640
And the component itself is not that complex.
7
00:00:19,640 --> 00:00:22,900
It uses state and it uses use effect.
8
00:00:22,900 --> 00:00:24,990
So that in use effect,
9
00:00:24,990 --> 00:00:28,250
we send the HTTP request to this dummy API
10
00:00:28,250 --> 00:00:31,130
to fetch some dummy posts.
11
00:00:31,130 --> 00:00:34,930
And then these posts are set as state here,
12
00:00:34,930 --> 00:00:38,223
and they are rendered out as a list down there.
13
00:00:39,340 --> 00:00:42,320
Now, if you would start this development server,
14
00:00:42,320 --> 00:00:43,830
you would see something like this
15
00:00:43,830 --> 00:00:45,470
because I don't have any styling
16
00:00:45,470 --> 00:00:48,210
since this is not about the styling at all,
17
00:00:48,210 --> 00:00:51,510
but you see that fetching and rendering these dummy posts
18
00:00:51,510 --> 00:00:56,313
from this dummy API, JSON placeholder works.
19
00:00:57,590 --> 00:00:59,730
Now, that works and here we are, of course,
20
00:00:59,730 --> 00:01:03,230
using some core mechanisms we learned about in this course,
21
00:01:03,230 --> 00:01:06,593
especially use effect for side effects like this.
22
00:01:07,870 --> 00:01:11,070
Now we wanna write tests for this component
23
00:01:11,070 --> 00:01:13,250
because, of course, this is also something
24
00:01:13,250 --> 00:01:15,330
which we typically wanna test,
25
00:01:15,330 --> 00:01:19,453
and there will be a couple of complexities related to that.
26
00:01:20,610 --> 00:01:23,820
Now, for that, let's first of all, add a new file,
27
00:01:23,820 --> 00:01:27,680
async test.js sounds like a fitting name.
28
00:01:27,680 --> 00:01:32,680
And in there, my tests failed because I have no tests yet.
29
00:01:32,870 --> 00:01:37,090
I'll add a new test suite, and I'll name it async component
30
00:01:38,830 --> 00:01:40,610
To have that as a wrapper.
31
00:01:40,610 --> 00:01:44,343
And then in here we can write the actual test code.
32
00:01:45,690 --> 00:01:49,820
Now, I will import the render and screen function
33
00:01:49,820 --> 00:01:51,230
from the testing library.
34
00:01:51,230 --> 00:01:54,690
So I'll grab that import and add that here as well.
35
00:01:54,690 --> 00:01:56,810
And then we wanna create a test,
36
00:01:56,810 --> 00:01:58,880
we wanna write a test where we test
37
00:01:58,880 --> 00:02:01,940
whether the posts are being rendered correctly.
38
00:02:01,940 --> 00:02:04,703
That could be the first test, which you wanna write.
39
00:02:06,400 --> 00:02:10,800
So here I'll say renders posts, that's my test,
40
00:02:10,800 --> 00:02:14,763
or renders posts if request succeeds.
41
00:02:16,520 --> 00:02:19,420
And then here, this is our testing code.
42
00:02:19,420 --> 00:02:24,420
We now, of course, wanna render this async component.
43
00:02:25,250 --> 00:02:28,640
So we should import this async component
44
00:02:28,640 --> 00:02:32,390
from this async file here and render it.
45
00:02:32,390 --> 00:02:35,303
That's our arrange step.
46
00:02:36,180 --> 00:02:38,340
Then we don't really need to act
47
00:02:38,340 --> 00:02:41,540
because rendering it is already everything I wanna do,
48
00:02:41,540 --> 00:02:45,540
since we will then fetch and set posts automatically
49
00:02:45,540 --> 00:02:47,360
because of user fact.
50
00:02:47,360 --> 00:02:49,350
So no other step is required.
51
00:02:49,350 --> 00:02:52,520
And therefore we can now dive into the assertion.
52
00:02:52,520 --> 00:02:57,310
And for that, I wanna check if some list items were rendered
53
00:02:57,310 --> 00:03:00,390
because I noted if list items were rendered,
54
00:03:00,390 --> 00:03:03,140
posts were fetched correctly because otherwise,
55
00:03:03,140 --> 00:03:05,243
no list items would have been rendered.
56
00:03:06,720 --> 00:03:09,290
So therefore, we can reach out to our screen.
57
00:03:09,290 --> 00:03:12,810
And now we'll find out if list items were rendered.
58
00:03:12,810 --> 00:03:15,320
And there are various ways of getting access.
59
00:03:15,320 --> 00:03:18,960
Here, I wanna get access by role
60
00:03:18,960 --> 00:03:22,480
because getting access by role will allow me to find out
61
00:03:22,480 --> 00:03:24,820
if there are list items on the screen,
62
00:03:24,820 --> 00:03:29,773
since list item is a role HTML elements can assume.
63
00:03:30,780 --> 00:03:33,730
To find out about all supported roles,
64
00:03:33,730 --> 00:03:36,963
I also attached a link with more information on that.
65
00:03:38,210 --> 00:03:40,760
So here we could use get by role.
66
00:03:40,760 --> 00:03:44,250
However, since I expect to actually
67
00:03:44,250 --> 00:03:49,250
have multiple list items, we should use get all by role,
68
00:03:49,920 --> 00:03:52,690
because get by role would fail
69
00:03:52,690 --> 00:03:57,380
if we have more than one item with that specified role.
70
00:03:57,380 --> 00:04:00,350
So here I wanna get all by role.
71
00:04:00,350 --> 00:04:03,570
And then the role here is list item.
72
00:04:03,570 --> 00:04:06,883
You find that role in that attached document.
73
00:04:08,640 --> 00:04:12,490
So that's the role by which I wanna select items.
74
00:04:12,490 --> 00:04:17,490
And therefore here, I hopefully have my list item elements
75
00:04:17,630 --> 00:04:21,630
which will be an array of HTML elements.
76
00:04:21,630 --> 00:04:25,903
And the expectation now would be that list item elements,
77
00:04:26,830 --> 00:04:29,280
this array is not empty
78
00:04:29,280 --> 00:04:31,820
because if this array of items is empty,
79
00:04:31,820 --> 00:04:34,480
we know that no items were rendered,
80
00:04:34,480 --> 00:04:37,123
and that of course is not the desired result.
81
00:04:38,090 --> 00:04:42,670
So here I wanna check that this is not empty
82
00:04:42,670 --> 00:04:46,413
so that it does not have a length of zero.
83
00:04:47,420 --> 00:04:51,010
Two half length allows us to check the length of an array,
84
00:04:51,010 --> 00:04:52,546
and here I only care
85
00:04:52,546 --> 00:04:56,230
about the fact that the length is not zero,
86
00:04:56,230 --> 00:04:58,573
so this is therefore my expectation.
87
00:04:59,420 --> 00:05:03,140
And you will typically be able to express your expectation
88
00:05:03,140 --> 00:05:05,670
with different combinations here.
89
00:05:05,670 --> 00:05:08,823
I'm going for this expectation here.
90
00:05:10,300 --> 00:05:13,610
Now, if I saved this and my tests run, however,
91
00:05:13,610 --> 00:05:16,580
you will see that this fails.
92
00:05:16,580 --> 00:05:18,370
You see that this fails
93
00:05:18,370 --> 00:05:21,200
because we're unable to find an accessible element
94
00:05:21,200 --> 00:05:22,783
with the role, list item.
95
00:05:23,740 --> 00:05:27,510
So somehow it fails to get list items.
96
00:05:27,510 --> 00:05:29,650
And to understand this error,
97
00:05:29,650 --> 00:05:34,450
it is important to understand that get all by role,
98
00:05:34,450 --> 00:05:39,450
just like the query methods you have here,
99
00:05:39,740 --> 00:05:43,803
will instantly look for these elements on the screen.
100
00:05:44,780 --> 00:05:48,610
But keep in mind that here we are sending an HTTP request,
101
00:05:48,610 --> 00:05:51,670
which is an asynchronous action.
102
00:05:51,670 --> 00:05:55,000
So therefore the posts are not there immediately.
103
00:05:55,000 --> 00:05:57,110
Instead, this component renders,
104
00:05:57,110 --> 00:06:00,200
and initially it renders with an empty array here,
105
00:06:00,200 --> 00:06:01,950
with an empty array of posts.
106
00:06:01,950 --> 00:06:05,163
So therefore initially, there are no list items.
107
00:06:06,150 --> 00:06:09,000
Then after this first render cycle,
108
00:06:09,000 --> 00:06:11,040
this effect immediately runs.
109
00:06:11,040 --> 00:06:12,950
And then this request is sent.
110
00:06:12,950 --> 00:06:15,820
And once the response is there, the state is updated,
111
00:06:15,820 --> 00:06:18,520
and then this component re-renders,
112
00:06:18,520 --> 00:06:21,053
this time with list items.
113
00:06:21,910 --> 00:06:25,290
But the initial render cycle does not have list items
114
00:06:25,290 --> 00:06:27,480
because there are no posts initially,
115
00:06:27,480 --> 00:06:29,370
because fetching that post data
116
00:06:29,370 --> 00:06:31,923
takes a couple of milliseconds or seconds.
117
00:06:33,280 --> 00:06:34,850
And that's our problem here.
118
00:06:34,850 --> 00:06:36,410
With get all by role,
119
00:06:36,410 --> 00:06:39,590
we immediately get all these items on the screen,
120
00:06:39,590 --> 00:06:41,040
and initially there are none.
121
00:06:42,350 --> 00:06:44,570
Now, there is a simple work around, though.
122
00:06:44,570 --> 00:06:49,223
Instead of get all by role, you can use find all by role.
123
00:06:50,160 --> 00:06:54,690
The difference is that find all by role or in general,
124
00:06:54,690 --> 00:06:57,160
those find queries which you can use
125
00:06:57,160 --> 00:07:02,160
instead of the get queries, these queries return a promise.
126
00:07:02,720 --> 00:07:04,970
Here you get back a promise,
127
00:07:04,970 --> 00:07:07,810
and actually react testing library
128
00:07:07,810 --> 00:07:11,610
will basically reevaluate the screen
129
00:07:11,610 --> 00:07:15,230
a couple of times until this succeeds.
130
00:07:15,230 --> 00:07:18,576
So therefore now, this will then wait for this
131
00:07:18,576 --> 00:07:20,583
HTTP request to succeed.
132
00:07:22,120 --> 00:07:26,670
For find all by role, you can also specify a third argument.
133
00:07:26,670 --> 00:07:29,880
The second argument allows you to set exact and so on.
134
00:07:29,880 --> 00:07:32,290
The third argument is another object
135
00:07:32,290 --> 00:07:34,893
where you can set that timeout period.
136
00:07:35,960 --> 00:07:38,320
The default here is one second.
137
00:07:38,320 --> 00:07:40,970
So if your items are not there after one second,
138
00:07:40,970 --> 00:07:42,800
this would still fail.
139
00:07:42,800 --> 00:07:45,430
Here, the default of one second shuts of flies,
140
00:07:45,430 --> 00:07:50,430
and now we do fetch those items after one second at most.
141
00:07:50,470 --> 00:07:52,850
And most importantly, we don't just look
142
00:07:52,850 --> 00:07:57,600
at the rendered component immediately, but we wait to see
143
00:07:57,600 --> 00:08:01,463
if we can find that item at a later point of time.
144
00:08:02,480 --> 00:08:05,510
Now, I'm getting some red squiggly lines here because
145
00:08:05,510 --> 00:08:08,830
since this returns a promise, we should await this
146
00:08:08,830 --> 00:08:11,180
before we work on the result,
147
00:08:11,180 --> 00:08:14,173
because the result here is a promise, not an array.
148
00:08:15,270 --> 00:08:18,620
Thankfully, your test code can be async.
149
00:08:18,620 --> 00:08:21,010
You can add the async keyword here.
150
00:08:21,010 --> 00:08:24,000
So put in our words, your test here
151
00:08:24,000 --> 00:08:26,260
can actually return a promise.
152
00:08:26,260 --> 00:08:29,150
And then jest, our test runner,
153
00:08:29,150 --> 00:08:31,800
will wait for this promise to resolve.
154
00:08:31,800 --> 00:08:36,440
So it will wait until your test is already done.
155
00:08:36,440 --> 00:08:40,350
And now therefore here we should add the await keyword.
156
00:08:40,350 --> 00:08:42,250
Now, this here is an array,
157
00:08:42,250 --> 00:08:44,293
and now this hopefully succeeds.
158
00:08:45,380 --> 00:08:48,250
If I now save this, the test runs again,
159
00:08:48,250 --> 00:08:52,550
and now we see that we get this success output here.
160
00:08:52,550 --> 00:08:55,853
We are able to successfully render those posts.
161
00:08:58,530 --> 00:09:02,240
And now I reran all my tests by pressing a again,
162
00:09:02,240 --> 00:09:05,200
and you'll see all tests passed here.
163
00:09:05,200 --> 00:09:10,023
So this works, but this actually is still not ideal.
13163
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.