# Testing a hook with a state update - Fri 2nd Oct, 2020
I wanted to write some tests for my `useFilters` hook. This hook handles persisting selected filters to storage, fetchign them from storage, creating the query string for the feed query, and managing the filter Formik state.
The main thing I wanted to test was the returned `filterParams` string, as this needs to be correct.
First thing was to mock the storage library set and get methods:
```typescript=
jest.mock('my-storage-lib', () => ({
get: jest.fn(),
set: jest.fn().mockResolvedValue('Successfully saved'),
}))
```
The next challenging part was that my hook uses a `useEffect` hook to fetch the persisted filters from storage and set back into Formik state. Since this state update is not "controlled" (ie. controlled by a prop like in [the hooks testing library example](https://github.com/testing-library/react-hooks-testing-library#usecountertestjs)), I would both get the dreaded `act` warning, and the `filterParams` value wasn't correct in the test.
After some trial and error, this was the solution:
```typescript=
jest.spyOn(myStorageLib, 'get').mockResolvedValue(JSON.stringify(mockInitialValues))
const { result, rerender } = renderHook(() => useFilters(), { wrapper: Wrapper })
await act(async () => {
rerender(true)
})
expect(result.current.filterParams).toBe(expected)
```
You need to wait for the hook to `renrender` asynchronously before calling your expect.
```typescript=
test.each`
case | myFilter | groups | customFilters | expected
${1} | ${null} | ${[]} | ${[]} | ${expected1}
${2} | ${myFilter} | ${[group]} | ${[customFilter]} | ${expected2}
${3} | ${myFilter} | ${[]} | ${[]} | ${expected3}
${4} | ${null} | ${[group]} | ${[customFilter]} | ${expected4}
`('Case $case: it should return $expected', async ({ myFilter, groups, customFilters, expected }) => {
jest.spyOn(RNSecureStorage, 'get').mockResolvedValue(JSON.stringify(mockInitialValues))
const { result, rerender } = renderHook(() => useFilters(), { wrapper: Wrapper })
await act(async () => {
rerender(true)
})
expect(result.current.filterParams).toBe(expected)
})
```
I also used the decent [react-native-collapsible](https://github.com/oblador/react-native-collapsible) instead of building my own accordion component for the filters.
###### tags: `programmingjournal` `2020` `C+` `filters` `hooks` `testing` `hookstesting` `mocks` `accordion`