|
2 | 2 |
|
3 | 3 | This recipe shows how simple it is to test your derived state with **simplux**. |
4 | 4 |
|
5 | | -If you are new to **simplux** there is [a recipe](../getting-started#readme) that will help you get started before you follow this recipe. |
| 5 | +If you are new to computing derived state with **simplux** there is [a recipe](../computing-derived-state#readme) that will help you get started before you follow 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/basics/testing-derived-state). |
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/selectors redux -S |
| 13 | +``` |
| 14 | + |
| 15 | +We also need to activate the selectors extension by importing the package. You can either add this import to every test file or do it once globally with the mechanism your test framework provides. This recipe uses [Jest](https://jestjs.io/) which allows us to specify a global setup file. |
| 16 | + |
| 17 | +```ts |
| 18 | +// in jest.setup.ts |
| 19 | +import '@simplux/selectors' |
| 20 | +``` |
| 21 | + |
| 22 | +```js |
| 23 | +// in jest.config.js |
| 24 | +module.exports = { |
| 25 | + setupFiles: ['<rootDir>/jest.setup.ts'], |
| 26 | + // + any other config you need |
| 27 | +} |
| 28 | +``` |
| 29 | + |
| 30 | +Now we're ready to go. |
| 31 | + |
| 32 | +Computing derived state for **simplux** modules is done with _selectors_. Selectors are very simple to test as you will see. For this recipe we use a simple counter module with two selectors. |
| 33 | + |
| 34 | +```ts |
| 35 | +import { createSimpluxModule } from '@simplux/core' |
| 36 | + |
| 37 | +const { setState, createSelectors } = createSimpluxModule({ |
| 38 | + name: 'counter', |
| 39 | + initialState: { |
| 40 | + counter: 0, |
| 41 | + }, |
| 42 | +}) |
| 43 | + |
| 44 | +const { plusOne, plus } = createSelectors({ |
| 45 | + plusOne: ({ counter }) => counter + 1, |
| 46 | + plus: ({ counter }, amount: number) => counter + amount, |
| 47 | +}) |
| 48 | +``` |
| 49 | + |
| 50 | +Let's start by testing our `plusOne` selector. The recommended approach is to test the selector in isolation by calling it directly. |
| 51 | + |
| 52 | +```ts |
| 53 | +describe('plusOne', () => { |
| 54 | + it('returns the counter plus one', () => { |
| 55 | + const result = plusOne({ counter: 10 }) |
| 56 | + expect(result).toBe(11) |
| 57 | + }) |
| 58 | +}) |
| 59 | +``` |
| 60 | + |
| 61 | +However, in certain scenarios it may be useful to test the selector with the module's latest state. To achieve this we can use `withLatestModuleState` after setting the module's state to the required value. |
| 62 | + |
| 63 | +```ts |
| 64 | +describe('plusOne', () => { |
| 65 | + it('returns the counter plus one', () => { |
| 66 | + setState({ counter: 20 }) |
| 67 | + const result = plusOne.withLatestModuleState() |
| 68 | + expect(result).toBe(21) |
| 69 | + }) |
| 70 | +}) |
| 71 | +``` |
| 72 | + |
| 73 | +Both of these approaches also work with selectors that take arguments. |
| 74 | + |
| 75 | +```ts |
| 76 | +describe('plus', () => { |
| 77 | + it('returns the sum of the counter and the amount', () => { |
| 78 | + const result1 = plus({ counter: 10 }, 5) |
| 79 | + expect(result1).toBe(15) |
| 80 | + |
| 81 | + setState({ counter: 20 }) |
| 82 | + const result2 = plus.withLatestModuleState(5) |
| 83 | + expect(result2).toBe(25) |
| 84 | + }) |
| 85 | +}) |
| 86 | +``` |
| 87 | + |
| 88 | +And that is all you need for testing your derived state with **simplux**. |
| 89 | + |
| 90 | +By now you are certainly curious how **simplux** can help you in more complex scenarios. Our [other recipes](../../../../..#recipes) are an excellent starting point for this. |
0 commit comments