|
1 | 1 | # Recipe: testing side effects |
2 | 2 |
|
3 | | -This recipe gives you some advice for testing side effects. |
| 3 | +This recipe gives you some advice on how to test your side effects (like loading data from your API). |
4 | 4 |
|
5 | | -If you are new to **simplux** there is [a recipe](../../basics/getting-started#readme) that will help you get started before you follow this recipe. |
| 5 | +If you are new to **simplux** there is [a recipe](../../basics/getting-started#readme) that will help you get started before you follow this recipe. The recipe for [performing side effects](../performing-side-effects#readme) is also important for following this recipe. |
6 | 6 |
|
7 | 7 | > You can play with the code for this recipe in this [code sandbox](https://codesandbox.io/s/github/MrWolfZ/simplux/tree/master/recipes/advanced/testing-side-effects). |
8 | 8 |
|
9 | | -This recipe is still a work-in-progress. |
| 9 | +Before we start let's install all the packages we need. |
| 10 | + |
| 11 | +```sh |
| 12 | +npm i @simplux/core @simplux/testing redux -S |
| 13 | +``` |
| 14 | + |
| 15 | +Now we're ready to go. |
| 16 | + |
| 17 | +For this recipe we use a simple scenario: loading data from an API. Let's create a module for this. |
| 18 | + |
| 19 | +```ts |
| 20 | +interface Todo { |
| 21 | + id: string |
| 22 | + description: string |
| 23 | + isDone: boolean |
| 24 | +} |
| 25 | + |
| 26 | +interface TodoState { |
| 27 | + [id: string]: Todo |
| 28 | +} |
| 29 | + |
| 30 | +const initialState: TodoState = {} |
| 31 | + |
| 32 | +const todosModule = createSimpluxModule({ |
| 33 | + name: 'todos', |
| 34 | + initialState, |
| 35 | +}) |
| 36 | + |
| 37 | +const { setTodoItems } = createMutations(todosModule, { |
| 38 | + setTodoItems(state, items: Todo[]) { |
| 39 | + for (const id of Object.keys(state)) { |
| 40 | + delete state[id] |
| 41 | + } |
| 42 | + |
| 43 | + for (const item of items) { |
| 44 | + state[item.id] = item |
| 45 | + } |
| 46 | + }, |
| 47 | +}) |
| 48 | +``` |
| 49 | + |
| 50 | +We want to load the todo items from our API. As we learned in the recipe for [performing side effects](../performing-side-effects#readme) we can create an effect for this. |
| 51 | + |
| 52 | +```ts |
| 53 | +// this effect first calls an HTTP API and then performs some post-processing |
| 54 | +// on the client (in a typical application this post processing would most |
| 55 | +// likely already be done in the API but it serves as a good example for this |
| 56 | +// recipe) |
| 57 | +const loadTodosFromApi = createEffect(async (includeDoneItems: boolean) => { |
| 58 | + await loadItemsViaHttp() // to be implemented, see below |
| 59 | + |
| 60 | + // do some post processing |
| 61 | + return todos.filter(t => !t.isDone || includeDoneItems) |
| 62 | +}) |
| 63 | +``` |
| 64 | + |
| 65 | +How are we going to test this and what exactly are we even testing here? There are two parts: 1) the call to the HTTP API, and 2) the post processing logic. 2) is the real logic that we should test and 1) is something that we certainly do not want to execute during our test, so we should mock it. Depending on your tech stack the library you use for making HTTP calls probably already provides a way to mock HTTP calls, in which case we recommend you use that library's testing capabilities. However, alternatively we could (and I am sure you have already guessed this) just make `loadItemsViaHttp` an effect itself. |
| 66 | + |
| 67 | +```ts |
| 68 | +const loadItemsViaHttp = createEffect(async () => { |
| 69 | + // call the API |
| 70 | +}) |
| 71 | +``` |
| 72 | + |
| 73 | +This way we can use **simplux**'s mocking capabilities to mock this call. If you go this route you could also create lower-level generic effects for HTTP calls, e.g. for `GET` calls: |
| 74 | + |
| 75 | +```ts |
| 76 | +const get = createEffect(async (url: string) => { |
| 77 | + // call the API |
| 78 | +}) |
| 79 | +``` |
| 80 | + |
| 81 | +Once we have 1) mocked we can easily test the post-processing logic from 2) by simply calling the `loadTodosFromApi`. |
| 82 | + |
| 83 | +> There are alternative designs to the effect above that would allow testing the filtering logic without the effect, e.g. by extracting it into a separate function. How you want to structure your effects is completely up to you. |
| 84 | +
|
| 85 | +And that how simple it is to test your side effects with the help of **simplux**. |
| 86 | + |
| 87 | +Have a look at our [other recipes](../../../../..#recipes) to learn how **simplux** can help you make your life simple in other situations. |
0 commit comments