Bodhisattva in Training

January 22, 2008 Unit Testing

Shifting the Focus

Last week I was having fun pair programming and TDD’n.  This was my first time pairing with my new friend so we naturally had to work through our differences.  One in particular was about a difference in unit testing and doubling (mocking) has stuck me with through the weekend.  My partner wanted to test and double protected members.  I was concerned that this was testing implementation and would bite us in the butt later by increasing the level of effort to refactor.  Another member of the team has no experience with test doubles beyond home grown simple stubs.  Working to explain the situations in which you would and would not want to use mocks, stubs, spys, etc has stuck with me too.  Particularly the distinction between state based testing and interaction based testing.

I see TDD as a design activity and not a testing activity.  I find it unfortunate that the word test is in TDD.  So saying state based testing and interaction based testing is not helping the situation.  I am going to start saying state based design and interaction based design.

When I was unguing that writing a test for a protected member was testing implementation I really wanted to say something like this is no longer a design activity.  Instead I resorted to calling on Gerard’s Preface to provide a better vision of the woes of unit testing.  At the time we were working on design, we were working oh the interaction between some of our classes.  Later when we where working with the interaction between one of our classes and an external class I felt something shift and could not put a name to it.  I have it now, the shift was from internal interactions and design to external interactions and implementation.  We ended up using mocks in both cases testing design for internal interactions and implementation for external interactions.  The external interaction we were mocking was simplistic, this is not always the case.  If the interaction had not been so simplistic we would have gone straight to integration tests.  To be clear we wrote integration tests as well.  I was attracted to the mocked unit tests for their speed of execution and reliability over the slow execution times and external service dependencies of the integration tests.  Not to mention how this would play an even bigger role if we start using a pipeline build.  I want the most feedback I can get in a 5 minute build and mocked external dependencies gave it to me, this time.

I wonder if TypeMock can play a role in improving this situation.  To be clear mocking the external dependency will not normally drive the implementation.  In essence I have duplicated effort in testing the external interaction, once with mocks and once with the real thing.  It seems to me that with the technologies that TypeMock is using you could write an integration test, specify the types or namespaces to record, execute the integration test while recording, and save off the record for playback.  With the playback you could then run those same integration tests in mocked mode, everything that you had specified to be recorded now being mocked.  You would have the benefit of in memory, fast running, tests and full integration tests with only a little extra effort.

2 to “Shifting the Focus”

  1. Colin Jack says...

    This is exactly the topic I’ve been thinking/blogging about myself over the last few weeks.

    As you say TDD should be a design activity but when you get down to it everyone uses it differently. Reading the mockobjects.com content has really started to bring this home to me and I tried to some of it in this blog entry: http://colinjack.blogspot.com/2008/01/how-you-test-influences-how-you-design.html

    Anyway as I say What fascinates me is that everyone does things differently. Take my approach as an example, and I should first say that I normally work on business code so what I say here mainly applies to my views on testing the domain model and below. I tend to favor state based testing and in fact object mothers, where we do mock we thus use TypeMock. I also *tend* to try to write most of my main tests against the public interfaces to the domain, so if I extract a class and make it internal I sometimes would still test it through the calling public class.

    These decisions totally influence how I design. I tend to rely on refactoring a lot and although TDD drives the design of my classes/methods I don’t then use it to drive me to extract interfects and inject.

    I do use interaction testing but mainly for interactions with service style classes. I don’t use it to help me specify LSP style interfaces when a Customer interacts with an Order though, as I’m not sure those interfaces would be that useful.

    Anyway this was a long comment, but like I say I think its an interesting topic!

  2. Gil Zilberfeld says...

    We had a few discussions on whether we would recommend using Typemock in integration tests using Fitnesse. It is possible of course, but should people use this method? We think that if you use it for mocking to test specific parts of the system in addition to full system tests, not instead of, it can give you a great safety net. It can also improve your performance if you mock database, IO and such. But again, it’s not a replacement for full system tests.

Leave a comment