Skip to content

Commit 4f48c04

Browse files
committed
zustand betterments
1 parent 4daa0d9 commit 4f48c04

File tree

2 files changed

+20
-34
lines changed

2 files changed

+20
-34
lines changed

src/content/6/en/part6b.md

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,15 +1018,15 @@ expect(counter.current).toBe(0)
10181018
10191019
As we can see, to access the hook itself we still need to take the <i>current</i> field from the object returned by <i>renderHook</i>, which corresponds to the hook's current value.
10201020
1021-
> ### What is act?
1021+
> #### What is act?
10221022
>
10231023
> <i>act</i> is a helper function that ensures all state updates and their side effects have been processed before the test code continues.
10241024
>
10251025
> When a state change occurs in a React component or hook, React does not update the state immediately but queues the updates. act forces these queued updates to be executed.
10261026
>
10271027
> Without act, a test might check the state before React has had time to update it, causing the test to fail or give incorrect results.
10281028
>
1029-
> React Testing Library wraps many of its functions (such as fireEvent, userEvent) in act automatically, but when testing hooks directly it is often needed manually, or by using the act provided by renderHook.
1029+
> React Testing Library wraps many of its functions (such as fireEvent, userEvent) in act automatically, but when testing hooks directly it is usually needed.
10301030
10311031
Testing via hooks uses React Testing Library and renders the hooks in a real React context using jsdom. This approach is considerably slower than tests that use the store directly, so if the hooks do not contain complex logic, it may be sufficient to run the tests using the store directly.
10321032
@@ -1070,6 +1070,7 @@ const useNoteStore = create(set => ({
10701070
export const useNotes = () => {
10711071
const notes = useNoteStore((state) => state.notes)
10721072
const filter = useNoteStore((state) => state.filter)
1073+
10731074
if (filter === 'important') return notes.filter(n => n.important)
10741075
if (filter === 'nonimportant') return notes.filter(n => !n.important)
10751076
return notes
@@ -1168,17 +1169,6 @@ describe('useNoteActions', () => {
11681169
const { result: notesResult } = renderHook(() => useNotes())
11691170
expect(notesResult.current[0].important).toBe(true)
11701171
})
1171-
1172-
it('setFilter updates filter', () => {
1173-
const { result: actionsResult } = renderHook(() => useNoteActions())
1174-
const { result: filterResult } = renderHook(() => useFilter())
1175-
1176-
act(() => {
1177-
actionsResult.current.setFilter('important')
1178-
})
1179-
1180-
expect(filterResult.current).toBe('important')
1181-
})
11821172
})
11831173
```
11841174
@@ -1237,7 +1227,7 @@ await act(async () => {
12371227
})
12381228
```
12391229
1240-
Since this is an asynchronous function, the completion of the call must be awaited with the <i>await</i> command.
1230+
Since this is an asynchronous function, the completion of the call must be awaited with the <i>await</i> keyword.
12411231
12421232
Finally, the test verifies that the store's state contains the same list of notes that the mocked <i>noteService.getAll</i> returned:
12431233
@@ -1280,6 +1270,8 @@ describe('useNotes filtering', () => {
12801270
})
12811271
```
12821272
1273+
The state is initialized with two notes, one of which is important and the other is not. The three test cases verify that <i>useNotes</i> returns the correct notes for all filter values.
1274+
12831275
The application's final code is on [GitHub](https://github.com/fullstack-hy2020/zustand-notes/tree/part6-6) in the branch <i>part6-6</i>.
12841276
12851277
</div>

src/content/6/fi/osa6b.md

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ Kun Redux DevTools -laajennus on asennettuna selaimeen, voidaan storen tilaa ja
831831
832832
### Zustand-storejen testaaminen
833833
834-
Tarkastellaan vielä lopuksi Zustand-storejen testausta Vitestillä.
834+
Tarkastellaan vielä lopuksi Zustand-storejen testaamista Vitestillä.
835835
836836
Aloitetaan yksinkertaisuuden vuoksi laskurin storesta:
837837
@@ -895,13 +895,15 @@ describe('counter store', () => {
895895
})
896896
```
897897
898-
Testit ovat varsin suoraviivaiset, hyödyntävät storen funktiota [getState](https://zustand.docs.pmnd.rs/reference/apis/create#returns), joiden avulla ne pääsevät lukemaan storen tilaa, sekä suorittamaan storen funktiota.
898+
Testit ovat varsin suoraviivaiset ja hyödyntävät storen funktiota [getState](https://zustand.docs.pmnd.rs/reference/apis/create#returns), joiden avulla ne pääsevät lukemaan storen tilaa sekä suorittamaan storen funktiota.
899899
900900
Ennen jokaista testiä store palautetaan alkutilaan <i>beforeEach</i>-lohkossa storen funktion [setState](https://zustand.docs.pmnd.rs/reference/apis/create#returns) avulla.
901901
902-
Storen palauttaminen alkutilaan on tapauksessamme yksinkertaista. Aina ei välttämättä näin ole. Zustandin [dokumentaatio](https://zustand.docs.pmnd.rs/learn/guides/testing#vitest) neuvoo tavan, miten storeista voidaan luoda testejä varten versio, joka asetetaan automaattisesti alkutilaan ennen jokaista testiä. Tapa on kuitenkin sen verran monimutkainen ja meille tarpeeton, joten emme siihen nyt mene.
902+
Storen palauttaminen alkutilaan on tapauksessamme yksinkertaista. Aina ei välttämättä näin ole. Zustandin [dokumentaatio](https://zustand.docs.pmnd.rs/learn/guides/testing#vitest) neuvoo tavan, miten storeista voidaan luoda testejä varten versio, joka asetetaan automaattisesti alkutilaan ennen jokaista testiä. Tapa on kuitenkin sen verran monimutkainen ja meille tarpeeton, että emme siihen nyt mene.
903903
904-
Testit siis käyttävät storea suoraan. Jos storejen käyttöön on toteutettu custom hookeina monimutkaisempaa logiikkaa, saattaa olla tarpeen tehdä testit siten, että ne myös hyödyntävät hookkeja. Laskurissa storen käyttö tapahtuu hookien <i>useCounter</i> ja <i>useCounterControls</i> kautta:
904+
Testit siis käyttävät storea suoraan. Jos storejen käyttöön on toteutettu custom hookeina monimutkaisempaa logiikkaa, saattaa olla tarpeen tehdä testit siten, että ne myös hyödyntävät hookkeja.
905+
906+
Laskurissa storen käyttö tapahtuu hookien <i>useCounter</i> ja <i>useCounterControls</i> kautta:
905907
906908
907909
```js
@@ -1018,15 +1020,15 @@ expect(counter.current).toBe(0)
10181020
10191021
Kuten huomaamme, päästäksemme hookiin itseensä käsiksi joudumme vielä ottamaan funktion <i>renderHook</i> palauttamasta oliosta kentän <i>current</i>, joka vastaa hookin nykyistä arvoa.
10201022
1021-
> ### Mikä act?
1023+
> #### Mikä on act?
10221024
>
10231025
> <i>act</i> on apufunktio, joka varmistaa että kaikki tilan päivitykset ja niiden aiheuttamat sivuvaikutukset on käsitelty loppuun ennen kuin testikoodi jatkuu.
10241026
>
10251027
> Kun React-komponentissa tai hookissa tapahtuu tilan muutos React ei päivitä tilaa välittömästi vaan jonottaa päivitykset. act pakottaa nämä jonossa olevat päivitykset suoritettaviksi
10261028
>
10271029
>Ilman actia testi saattaisi tarkistaa tilan ennen kuin React on ehtinyt päivittää sen, jolloin testi epäonnistuisi tai antaisi väärän tuloksen.
10281030
>
1029-
> React Testing Library käärii monet toimintonsa (kuten fireEvent, userEvent) automaattisesti act:iin, mutta hookeja suoraan testattaessa se tarvitaan usein manuaalisesti, tai käyttämällä renderHook:in tarjoamaa actia.
1031+
> React Testing Library käärii monet toimintonsa (kuten fireEvent, userEvent) automaattisesti act:iin, mutta hookeja suoraan testattaessa sitä on viisainta käyttää.
10301032
10311033
Hookien kautta tapahtuva testaaminen käyttää React Testing Libraryä, ja
10321034
renderöi hookit oikeassa React-kontekstissa jsdomin avulla. Tämä lähestymistapa on huomattavasti hitaampi kuin suoraan storea käyttävät testit, eli jos hookit eivät sisällä kompleksista logiikkaa, voi olla riittävää suorittaa testit suoraan storea käyttäen.
@@ -1071,6 +1073,7 @@ const useNoteStore = create(set => ({
10711073
export const useNotes = () => {
10721074
const notes = useNoteStore((state) => state.notes)
10731075
const filter = useNoteStore((state) => state.filter)
1076+
10741077
if (filter === 'important') return notes.filter(n => n.important)
10751078
if (filter === 'nonimportant') return notes.filter(n => !n.important)
10761079
return notes
@@ -1169,17 +1172,6 @@ describe('useNoteActions', () => {
11691172
const { result: notesResult } = renderHook(() => useNotes())
11701173
expect(notesResult.current[0].important).toBe(true)
11711174
})
1172-
1173-
it('setFilter updates filter', () => {
1174-
const { result: actionsResult } = renderHook(() => useNoteActions())
1175-
const { result: filterResult } = renderHook(() => useFilter())
1176-
1177-
act(() => {
1178-
actionsResult.current.setFilter('important')
1179-
})
1180-
1181-
expect(filterResult.current).toBe('important')
1182-
})
11831175
})
11841176
```
11851177
@@ -1208,7 +1200,7 @@ beforeEach(() => {
12081200
})
12091201
```
12101202
1211-
Jokaisen testin alussa mockatulle <i>noteServicelle</i> kerrotaan funktion [mockResolvedValue](https://vitest.dev/api/mock.html#mockresolvedvalue) kuinka sen tulee toimia testin kontekstissa:
1203+
Jokaisen testin alussa mockatulle <i>noteServicelle</i> kerrotaan funktion [mockResolvedValue](https://vitest.dev/api/mock.html#mockresolvedvalue) avulla kuinka sen tulee toimia testin kontekstissa:
12121204
12131205
```js
12141206
it('initialize loads notes from service', async () => {
@@ -1228,7 +1220,7 @@ it('initialize loads notes from service', async () => {
12281220
})
12291221
```
12301222
1231-
Aluksi testi määrittelee, että kutsuttaessa funktiota <i>noteService.getAll</i> palautetaan storelle taulukossa <i>mockNotes</i> olevat muistiinpanot.
1223+
Aluksi testi siis määrittelee, että kutsuttaessa funktiota <i>noteService.getAll</i> palautetaan storelle taulukossa <i>mockNotes</i> olevat muistiinpanot.
12321224
12331225
Testattava asia on funktion <i>initialize</i> kutsu:
12341226
@@ -1238,7 +1230,7 @@ await act(async () => {
12381230
})
12391231
```
12401232
1241-
Koska kyse on asynkronisesta funktiosta, tulee kutsun valmistumista odottaa komennolla <i>await</i>.
1233+
Koska kyse on asynkronisesta funktiosta, tulee kutsun valmistumista odottaa avainsanaa <i>await</i> käyttämällä.
12421234
12431235
Lopuksi testi varmistaa, että storen tilassa on sama lista muistiinpanoja, mitä mockattu <i>noteService.getAll</i> palautti:
12441236
@@ -1281,6 +1273,8 @@ describe('useNotes filtering', () => {
12811273
})
12821274
```
12831275
1276+
Tila alustetaan kahdella muistiinpanolla, joista toinen on tärkeä ja toinen ei. Kolme testitapausta tarkastavat, että <i>useNotes</i> palauttaa kaikilla filtterin arvoilla oikeat muistiinpanot.
1277+
12841278
Sovelluksen lopullinen koodi on [GitHubissa](https://github.com/fullstack-hy2020/zustand-notes/tree/part6-6) branchissa <i>part6-6</i>.
12851279
12861280
</div>

0 commit comments

Comments
 (0)