Lock-step Refactoring in Node.js (Part 3)
The story thus far…
In part two we refactored the Faker
object into a class. This allowed us to inject it into our Ancient
faker module. So now how to we use this to our advantage?
Stubbing using Sinon
Standalone test spies, stubs and mocks for JavaScript.
Works with any unit testing framework.
Sinon is a package used for creating spies, stubs and mocks. We will be using it specifically for stubbing. Because we now have access to the Random
faker module, we can stub that to ensure we get the correct value for an assertion.
What changes to we need to make?
So I installed the sinon and sinon-test packages into the project. The sinon-test package is used to ensure that stubs are cleaned up after the test has complete. This avoids the need to create a before and after hook that removes the stubbed methods.
Here is what the Ancient
faker module tests look like now.
Notice that we aren’t just stubbing the Faker.Random.element
method to return a value just because it was called. Instead we are making sure that we are also passing the correct array to the element
method, so we can be sure that when we run this outside of a test we will get a result from that array.
The refactoring is complete
I carried on this same pattern for each of the faker modules, and have not run into any random failures yet 🤞. For some modules it was a bit harder to implement due to some bits of data including placeholders that needed to be replaced by calls to another faker module, but other than that it was relatively painless to implement these changes.
Also, we still have 100% code coverage 😎
How did lock-step refactoring help?
Throughout each of these changes I was running tests. And after making each change, of which some were quite large, the tests were still passing. Having the old implementation alongside the new one also helped a great deal, as I knew what the new code had to do. And if I missed something out, then the tests would catch it!
The whole lock-step approach in a nut-shell could be described as a sort of code-swap operation. Because that is what it basically entails.
- Write the new code
- Swap the old code with the new code
- Delete the old code
That is how simple it should be 😄
Go ahead and try it out for yourself on your own projects and let me know how it goes 👍