I had it pointed out to me at the end of last year that I use Mocks too much. I isolate the class under test more than I might need to do. Isolation of a class has the most value at service boundaries. If other classes can safely be included in the test without side-effects, I’m actually testing more than jus the class under test.
This is a bad thing, right? No. Not necessarily. The tests purpose is to prove that the code solves it’s intended purpose. If by including more of the system that this piece of code interacts with, the test will be more tightly coupled to the actual use of the class.
If I isolate the class, non-API breaking changes in other classes might cause the requested system behavior to fail, but my test which tests the class in isolation will still pass. The purpose of my tests should naturally be to detect defects earlier.
As I considered this I went back to the places in our code-base where I feel TDD has really really helped me. And sure enough, almost no mocking in those tests, relying instead on actual objects. For me, this was sort of an eye opener.
How do I work without mock’s then?
One example is to use inheritance. If I isolate all calls to system-boundaries to a single method, I can inherit from the class under test and override that system-boundary specific piece of code. This allows me create “mocked” version of the class without the need for mocking libraries.
This is called Test-specific subclass. Thank you Patrik!
This method is even applicable to legacy code where mocking isn’t applicable.
Another example would be to use actual objects all the way, if possible. For databases for example you could create a temporary testing database if you have access to a database server. Depending how you access your data you might even be able to have an in memory database instead of an actual database. While this might mean you need to implement a test-class instead of mocking it. If the API doesn’t change all to often it might save you time compared to mocking.
http://xunitpatterns.com/Test-Specific%20Subclass.html
Funny thing. Some might remember my how I work with code, where you keep a list of issues you figure out as you work with the code.
Apparently Kent Beck presents this as a pattern called Test List.
I’m trying to embed it below, we’ll see how it goes.
Btw- if this embedding thing is more annoying then helpful, please let me know.
Quite interesting. We just finished an internal TDD course at RemoteX. During it I noticed one thing. How I write tests have changed quite a bit, just over the last few days.
Lately I’ve been doing a lot of testing in JavaScript using QUnit, and coming back from that to testing C# with Rhino Mocks was really an eye opener. One observation, which was also pointed out during to course, is that we use Rhino too much. Simply put, we have a tendency to mock more than we really need too.
I learned a new way to test objects the other day.
We had a consultant over to talk about a TDD course he will be holding for RemoteX internally. During the discussion the suggestion to test an object by mocking the object itself came up.
What you do is, you use Rhino mocks (or similar) to create a partial mock of the object under test. What you override is the methods that will result in external communication.
This requires you to put all communication code in a single method, which you then override using the partial mock. The test then becomes, is the method for external communication called.
This reduces the amount of mocking code needed for more coupled objects, and also reduces the “IoC container for testability” need. Allowing the IoC focus to be focused on interchangeable parts.
I developed a JQuery Application using TDD these last couple of days. During the testing I used a new technique for testing my AJAX calls, so I thought I’d blog about how I test AJAX calls done by JQuery.
First of you have to see that there are several things to test in just a simple $.ajax call. There is not only all the combinations of the options, there is the behaviour of what to do when the call fails, or is successfull, or times out. There is a boundary between the JavaScript code and the server, will you pass it? Will you test the communication with a server, or even a mocked server using an XML file?
I’ve been testing $.ajax get operations using XML files as a mocked server backend for a while, but recently I mocked it instead.
Mocking $.Ajax requests is quite easy. Before you execute the code that will make the AJAX call, you exchange the ajax function.
$.ajax() = function(options) { options.fail(); };
The above line of codes forces the following ajax calls to automatically execute their fail callbacks. The function can easily be changed to simulate different behaviour of the AJAX requests.
Using this technique there is a risk, that the tests your writing become whitebox testing. The ajax mocking code becomes twins of the code your testing, resulting in a verification that the code is written as is, but not testing that it does what it should do.
Some of the exercises covered in the previous post covered the aspect of analysing the end goal. Now, I’m sure that what we covered was no where near the available exercises. But doing several exercises servers a purpose, even if you already know your goal in life.
Each exercise allows to examine the goals from different angles. If you identify different goals using different angles, then perhaps you haven’t found the right goals, or just more of them. Either how they can increase your confidence in the goals you identify.
Now confidence is what we achieve with unit testing as well. In an way, we can see unit tests as a way to examine the code under test from a different angle. Different compared to the code that will execute the code under test.
Just a thought.
During the end of the the 20th century, IBM had a TV commercial that I’m quite fond of. I can’t find it on YouTube, but its quite short. There are two suites talking, one reading a magazine. The one with the magazine says “We need to be on the Internet”, the other asks, “Why?” the first replies “It doesn’t say”.
I’ve seen this approach applied to Software quality several times now.
Allot of managers are hearing good things about automated tests. This results in allot of in house improvement projects trying to solve the question “How can we get more automated tests”.
The problem is that the question is asked all wrong. What the question really should be is “How do we improve software quality?”.
The end result might as well be more automated tests. But if you have a team of developers whom have never worked with testing. Your product isn’t going to be testable, and they will need allot of help. Help to set them up, but first and foremost help to understand why it is important to, not test but, to produce High Quality working software.
Most developers do not believe that there is a problem with their quality of the software. Without getting the team to think about software quality while their working, automated testing will take a long time to get in place. Above all the investment on automated tests will have a longer Return of Investment.
Now automated tests might be a part of the end solution for improving the quality of software, but getting the discussion about software quality going in a well behaved manner can have so much more Return of Investment.
I wrote a blog post about how I work with code. The basic idea is that I record actions that I need to take as I work with the code in a format that is readable by the other developers in my team. In case I get run over by a truck they can see where I took off. Also its a way to record what and why I’m doing as I’m progressing through code written by someone else.
I got a response from a former colleague Anna who claimed I wouldn’t need to do it if I had automated tests. Even though Automated tests doesn’t have much to do with personal productivity at first glance, a recording of something that needs to be fixed could be a unit test. If developers run the tests often they are in my shelveset and they can see which pieces of the code I perceive bugs in.
In fact this is exactly what is being done as I work with TDD. Giving support to the fact that TDD can increase the productivity of a developer, following the same ideas presented in Getting Things Done.
Tests however doesn’t record suggestions for design improvements or actions such as “Ask x about icon y”. At Least not as far as I know.
I found a new tool for testing web-applications in IE today. It’s called IETester, and it allows me to test IE versions 5.5 to 8 in the same application. Which is great, since my Vista machine only runs 8 normally.
I use it to verify my Grails application in IE6. Tonight I managed to create a unit test capturing the issue I was experiencing in IE6, using IETester and QUnit, so now I know where to take off tomorrow.
However it isn’t that stable, I’m running it on a 64-bit machine which might add some extra strain on the application. But for me it needed to be re-started or crashed a few times while I was isolating the bug I am working on.