On Thursday we took a further look at automated testing. A couple of months ago we had a Code Jam focused on Continuous Integration, in that session we looked at automating the build as a whole, including running tests. In our last Code Jam, we paid greater attention to testing and automating those parts of a system that rely on external or difficult to configure components.
In the session we looked at the differences between state based testing and interaction based testing including the pro’s and con’s of the two approaches. We identified why mock based testing makes unit testing easier and discussed the layering that tends to occur when using mock based approaches. Shen Tham drew an excellent comparison between stubs and mocks, briefly discussing the concept of Inversion of Control (IOC) and how it applies to mocking (this is something we’ll look at more closely in a future Code Jam). Aaron Farr also showed us how he uses mocks when testing the Model View Presenter pattern.
A reasonably simple example was used to demonstrate the use of Mockito. The example is a simple but incomplete graphing application that shows how data retrieved from a feed can be provided to something that can render it. The intent is to show how the various components can be split from each other in such a way that they an be unit tested separately from any live system that needs to be configured. If you take a look at the code you will see that the data used in the graph can be sourced from any appropriate system such as databases, file systems, FTP and HTTP. Likewise, it should be easy to see that the data can easily be displayed in a variety of ways. It can be written to a stream (as per the example code), written to file, sent to a browser via HTTP, published to an FTP server as a file, the options are open. It should be obvious that the feed and display are independent provided the common application interfaces are adhered to. While the mocking and stubbing techniques don’t enforce this, they certainly make help make it easier.
We looked specifically at the following Open Source Java mocking frameworks:
For other languages you might want to have a look at the following tools:
- .NET: Rhino Mock, moq
- C: CMock - (ruby based) mock tools for C and Test Driven Development in Embedded Software
- Python: Mock, PyMock, pMock, pymox, Python Mocker
- PHP: SimpleTest
For further reading on Mocking I suggest the following:
In closing it is important to understand that an emphasis has been placed on testing at the unit level using mocks and stubs. There are many reasons for doing this. One must remember that unit testing alone is not sufficient to ensure complete and reliable integration with 3rd party systems. For this we must still write automated integration tests. However, these tests can be isolated in such a way that they are only executed by the continuous integration environment if they take too long to execute on a developer machine. Unit tests written with mocks and stubs are therefore not a replacement for integration or functional tests.
Many thank to Kalun Wong for his summary of the evening’s activities.