One of the hottest debates on unit-testing in my mind is the discussion about mocking components when creating unit-tests for your application. I personally think that this is one of the most important things that you really need to get right when building great software.
This article is not about how you mock, but rather a number of reasons why you should. I may be writing another one with general tips on how you can modify class structures to easily allow for mockups.
Reason one: Speed
The first reason to use mocks is speed. Quite simple, if you need to access a database from your unit-test, the test will be slower. While this may be a good test to see if the performance is ok, it’s not so great for when you have to wait for the test to finish. Most developers I know will start complaining and growling at their computer when stuff gets slow, so it’s best to keep stuff that is slow out of the unit-tests.
The same performance loss happens when accessing webservices. A SOAP call is always a lot slower than when you do a call to a mockup that directly returns a predefined result. See also availability.
Reason two: Dependencies
The second reason to mockup stuff in your application is the number of dependencies required to be able to run a unit-test. For example, if you need a database (Or more than one for that matter, I’ve seen applications that need it. In fact, I work on a system that requires this scenario) it’s not going to be that great to build a unit-test for even the simplest thing.
One of the first things that you will notice is the complexity involved in developing tests for your components. Setting up the environment right at the beginning of the unit-test is a must, however it shouldn’t take more than three minutes to do this. Any longer and you will feel drastically slowed down in your development process.
Also, when some components aren’t quite right yet, you might not be able to write tests for another component you are working on at the moment. I often hear from people that having components in a layer below the current component that are not implemented is not a good practice. However from my experience this happens sooner or later, because of various other constraints. Like for a example the requirement to have a simple prototype UI for the customer to take a look at. You don’t want to build the complete backend in this case and just implement a basic controller behind the user interface and mockup the rest of the stuff. You then have unit-tests for the controller, but not yet have a fully implemented system.
Reason three: Availability
In a service oriented environment it often happens that services from third parties crash or are otherwise not available to the application. The first day you implement a unit-test and it works fine, next morning you come in and the service was not available when the buildserver required it to complete the unit-test. It happens and it feels rather silly when you think about it.
The third reason to use mockups is availability. Whenever a component has a chance of not being available, use a stand-in. The system should be designed to allow this, so that you don’t get any evil surprises in the morning.
Reason four: There’s more than one developer
The fourth reason to use mocking is the team you work on. It often happens that components are build by different people. If you design the system right, you should be able to test your component without needing the real thing from you colleagues. This makes for faster development and a more fun working environment. People don’t have to wait for each other and the project manager doesn’t have to write off hours because of people waiting for other people’s components.
Reason five: Reproducable states
One of the important things about unit-tests is the possibility to mimick a specific state of the system. This can only be done effectively when the components can be easily reconfigured to reproduce a specific state.
I’m adding this reason to the list because of one specific issue. When you require a database or an external webservice for that matter it’s going to be quite hard to reproduce the same result for each test each time you run it.
Typically you use one database for the whole system to test on. The state of the database is going to change with each test and there’s no guarantee that the tests are run in the same order each time you run them. This requires developers to write code to restore the database state with each test, which is not only difficult to do, but can also cause technical issues with a failing database restore or a database server that one day is suddenly out of disk space and causes a build error.
It is much easier to configure mockups in the correct state than restoring a database in the correct state. It also helps to remove dependencies on data between unit-tests.
I seriously feel that unit-tests are important and that making them is a serious business. I also feel that mocking is an integral part of this process. I hope that people will get a better understanding of the why behind this and produce even better software than they are already doing now!
Enjoy your coding sessions 🙂 And feel free to add more reasons or remarks if you think I missed something.