So where should we start now? So the first thing we can do is to clean up the code. What we can do is a refactoring. I like to call extract custom hooks. This is one of my favorite features of hooks is that you can actually boot hooks from other hooks and they create these very nice interfaces.
So here all these big fat logic can just be extracted into a simple hook, and this hook can give you, okay, that's what's the memory of the calculator and what are the actions. And again, the code for the hook is just copy paste, it works. So how do we going to test this custom hook? This is the next step we needed to do.
So for testing this custom hook, there is this nice library called React hooks from React testing library, which allows you to very easy test the hook and what I like to do is I want to have a function called emit hook, which basically hides the boilerplate setting up the hook. And for example, I want to test the add action. So for the add action, it's just setting up the hook, adding cut value and checking that after the hook is reloaded, we have updated our value and we can basically test, okay, if I have two digits, they're added, and you can go through all the tests for that, for remove is very similar. You set up the hook, you just call it, you have this nice call function where you encapsulate this and you have all of this. And again, it's a bit long and I would link you to the slides in the end so you can dig through more.
And now when we have this test, which very thoroughly test our hook with all its edge cases, with all its workarounds, we can actually start refactoring this hook. The thing we are going to end up in the end from this big ball of mud is basically refactor this hook to use just a simple useReducer where we say, okay, we have a reducer function and in the end we have the same actions add, remove, reset, evaluate. And this is again the reducer scope. It's a bit more complex. It's a bit more split, but this actually tests our calculator and we actually have like a full test coverage. And again, the code for this presentation is leaving this address so we can click it and go to the details. I actually split into steps so you can see all the refactoring steps. And a couple of the final notes I want to say here is in the end, I'm actually removing all that code from the smoke test. I don't need it. What I have found in practice is usually when I write React components, they're either very dumb, like they get some data and render stuff, so there's not much value adding to test them as a unit test. Or the biggest logic and the biggest thing I have in my test is the hook code. Like usually, that's the place where a lot of the complexity of my system is. So I generally stopped doing React unit tests. And what I try to do on the unit test level is to just unit test the simple function, like for example, I could just as the reducer, I can just test the hook by itself and not test the React components. The way I'm sure that the React components work is through doing end to end testing with something like Cypress or something like Capybara, which actually tests my whole workflow because I very rarely have found bugs in my system, which were regarded to just the React component itself. Usually the bugs come from very complex hooks or when we have class components, class components. So yeah, that's basically what I wanted to share with you today.
Comments