Sunday, January 27, 2008

Working Effectively With Legacy Code

Although I've owned a copy for well over a year I've never felt like reading Working Effectively With Legacy Code but having just finished reading an excellent chapter I'm realizing this was a mistake.

As you probably know the book is really about getting code under test, legacy code being code without tests. Thus if you are working with a codebase with little or no test coverage, and where dependencies make it hard to test, it's going to be a very useful book.

Since we already have good test coverage and generally don't have any major problems getting our code under test I didn't think it was that relevant. However I just read an excellent chapter (6) that explains how to make changes to code that doesn't have tests whilst ensuring that your new code has tests. The chapter documents a few patterns:

  1. Sprout Method - You cannot get the method that you are adding the behavior to under test. Put the new behavior into a new method with its own tests, call the new method from the method you want to add the behavior to.
  2. Sprout Class - Perhaps you can't get the existing class under test or the new responsibility does not fit the existing class, create a new class for the new behavior. Hopefully by doing this you improve the design and have extracted a meaningful concept.
  3. Wrap Method - Take the existing method and extract the code from it into a new method, leaving the original method calling the new one. Now add a call to the new method that adds the behavior you want to add. This maintains the interface used by the callers.
  4. Wrap Class - Extract a decorator or a wrapper class that delegates to your existing class but adds behavior before/after the call(s). The book recommends using decorator sparingly but its useful when there are many class to the class being wrapped.

The book then goes on to compare the choices.

Like I really liked the section. It focusses on changes that allow you to get your code under test but they could be part of a process that eventually improves the design and brings your entire code base under test.

I also like the fact that he has given these changes simple memorable names, and for that reason alone I'm now glad I've started reading the book.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Wednesday, January 23, 2008

TDD Newsgroup - Interesting Threads

I've started to read the TDD newsgroup, which is great, and I thought I'd begin to keep track of threads that I've found useful:

  • Extract Class and TDD - I use refactoring a lot so I often end up with (hidden) extracted class that are only tested because the code that uses the extracted class is tested. This thread covers whether this is appropriate. I partricularly like the Method Use Rule post. Anyway my feeling after reading the thread is if I'm extracting to remove duplication then I should tested the extracted class itself, otherwise leaving the tests I have is a valid use. I'm also thinking that any class that is to be part of the ubiquitous langauge should always have its own tests, so even if you extract a specification and only use it once it needs to be tested in isolation.
  • Refactoring - Covers some of the same ground as the Extract Class and TDD one.
  • Mocking Concrete Objects - What I took away from this is that if you have an inteface, or if you think you can add a meaningful interface, then mock that interface if it suits. If you have a concrete class and don't want to add the interface then use real instances.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Styles Of TDD for your Domain Model

Having read a lot of mockobjects.com I'm beginning to understand need-driven development and the effect on design. This has made me want to re-read some old articles:

These are all good posts but I'm coming to the conclusion that there just isn't that much real content out there about how to use interaction testing as a design and testing activity for domain entities/value objects. Seems like a lot of people don't do it and so far the ones that do haven't written that much about it.

The content I have found has semed to be producing designs that I wouldn't be that interested in and although the idea of extracting role interfaces from high level domain entities interests me I can't find any real evidence that people are doing it meaningfully. I'm also not sure that doing it is going to improve the design that much.

Anyway I think for now I'm better focussing my design efforts on traditional DDD activities, whilst keeping an eye on what the BDD/mockobjects.com guys produce.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Johns New Blog

A colleague of mine John McDowall has a new blog. Its not as good as my blog but it may be the second best blog in the world.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Tuesday, January 22, 2008

Interesting Posts About Tests Influencing Design

Oddly I started reading a post by Jay Flowers, which led me to re-read a linked post at mockobjects.com which in turn led me to the most relevant post of all about testing domain classes. I'm glad I followed the links because there is some good info in these posts.

Shifting The Focus
Jay Flowers is thinking about testing and design at the minute too and has just posted about how it affects design in a post called Shifting The Focus.

Test Smell : Everything Is Mocked
I read the post Test Smell: Everything is mocked some time ago but never blogged about it but I do definitely think its worth reading.

I fully agree with the post, directly mocking external API's is often going to be a mistake and your better to use TDD to evolve a wrapper. I also think mocking value objects is a bit of a no-no.

Note there is a TDD thread related to mocking value objects.

Testing Domain Classes
J. B. Rainsberger has a post called A sign you're mocking too much which I whole heartedly agree with.

One of the main points in the post is summed up in this line "Never mock values, sometimes mock entities, but mock services freely". I agree with this and that's basically the way I test domain classes too:

  1. Value Objects - No reason to mock, they should be simple to construct.
  2. Entities - I tend to create real instances using Object Mother or Test Data Builder objects. Occassionally I'll stub an entity but very rarely will I mock it.
  3. Services - Mock away, including mocking repositories.

This also ties in nicely with Eric Evans' opinions from the Testing The Domain thread on the DDD forum. It also indicates that some DDD practitioners (including myself) are using TDD to influence design in ways other than those that we would get to if we purely used interaction testing.

I think I'm going to start to focus on looking at our domain tests and object mothers to see what they are telling us about problems with our current designs.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Monday, January 21, 2008

How You Test = How You Design

I've recently started reading through all the design related posts at mockobjects.com.

They are highly recommended and I agree with all of the theory behind them and a lot of the practices. However what interested me most was that despite this I don't design software in the same way as them.

Take the "Test Smell: I need to mock an object I can't replace (without magic)" post as an example. I love the design exercise that the author goes through, and extracting the Clock/SameDayChecker class is superb. Yet something about it made me realize that I don't design the way they do and amn't sure I want to...

Refactoring v Need To Mock
In the example the design improvement is driven by the need to replace the time in a test.

Now I can understand the need to replace the time but I would also say that if your the sort of designer than looks at the original code and sees that its not cohesive enough then your going to extract the SameDayChecker concept regardless.

Maybe I'm wrong though, would I have looked at the original code and thought "good enough". Possibly, and if there was no pain then that might have been fine. So the tests have perhaps forced us to a better design.

However that leaves me a little cold as if we didn't need to replace the time for testing, or if the incohesive code had nothing to do with an external dependency, then we'd have settled for the first option.

If we thus use this style of testing to drive our designs then we only get good designs if we make every piece of the code replacable...

Injection
I dunno but to me the whole IoC thing is heavily influenced by Robert Martins ideas of dependency inversion.

Thing is I don't think Robert Martin meant that every class should be replacable, or at least I never read it that way.

I also don't think it should be used as your primary design technique, as in I want to test Customer without CustomerMustHaveAddressRule so i'll extract the rule (good) then inject it into Customer (huh). Do I really need to inject my rules into the domain, if I do then fine but for many line of business applications this would be overkill.

My approach would be extract the rule (SRP/cohesion etc.) but then use it directly from the domain. I'm unlikely to replace one rule with another implementation.

Why It Matters
I actually think using interaction testing as a design technique is interesting but when I look at the Clock/SameDayChecker example I'm left a little unhappy.

Am I really going to ever replace the SameDayChecker in production, is it really a meaningful dependency that I want my domain class to show. To me the answer is "probably not" to both.

I also think that IoC and injection of dependencies is great. However I definitely do not think everything needs to be injected when it comes to domain models, and if you use the design technique described then I think that you could end up with decoupling that I wouldn't find useful.

Lots of decoupling, much of which does nothing but make the design more complex without ever being taken advantage of, is my worry with some of these techniques.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Roy Osherove - The Case For TypeMock

Roy Osherove has another post on the case for TypeMock.

For me the big one is that design for testability has its limits. Breaking encapsulation, interfaces over all your classes, injecting everything, virtual members everywhere. Those things can be good and they can also lead to klunky designs particular in domain/business code).

That doesn't mean that design for testability isn't good. However when I want to mock something without changing its design, because I'm quite happy with its current design, I turn to TypeMock.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Sunday, January 20, 2008

TDD Anti-Patterns

In comments to one of his blog entries Jeremy Miller linked to this good post on TDD Anti-Patterns. Definitely looking forward to the paper that the author of the post is writing.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Test Doubles and the Effect On Designs - Mock/Stub/Fake

Just got through reading the mockobjects article on the interaction test smell too many expectations.

It's a great article and made me want to try to bring together my understanding of what people mean when they talk about stubbing and mocking.

MockObjects.com - Stubs and Expectations
The article makes the distinction between Stubs and Expectations:

  1. Stub - Replace a dependend on component (DOC) so that you can get it to return known values.
  2. Expectation - Goes further by testing that we get the expected interaction with the DOC.

The idea is that if you program too many expecations into the test you get confusing tests that don't make it clear whats important.

XUnit Test Patterns - Stubs and Mock Objects
If you have read Meszaros's XUnit Test Patterns then you will know that in his view there are multiple types of Test Double and they are required to control two things:
  1. Indirect Inputs - If the system under test (SUT) uses the DOC and the DOC returns any values (even exceptions) that affect the SUT then you need to be able to make the DOC return these values in order to run your tests. If you can't get the DOC to do it then you replace it with a Test Double.
  2. Indirect Outputs - Encapsulation often means we don't have to care how an object does what it does, however when testing we do care and we therefore may want to test the interactions with the DOC (in the process writing the SUT to make its dependency on the DOC more obvious). In fact in some cases we may have no choice if the DOC does not produce any observable side effects.

Meszaros goes further and describes the means of getting the correct inputs into the SUT in as being through a control point and the means of verifying the indirect outputs as being through an observation point.

In Meszaros's terminology there are thus three main types of Test Double:

  1. Test Stub - Controls indirect inputs to the SUT.
  2. Test Spy - Acts as a Test Stub but also records calls so that the test can examine them.
  3. Mock Object - You pre-program it with the expected interactions and it will verify they happened.

Meszaros also discussed further classifications and how to configure/install the Test Doubles, as with the rest of the book it is very comprehensive.

Why It Matters
It seems like people are coming to the conclusion that it is important to differentiate between situations where you care about the expected interaction with an object and cases where you don't. If you don't make the differentiation your tests will be unnecessarily complex.

The interesting bit is then how the different types of Test Double affect your testing. I believe many people use Mock Objects when they really don't much care about the collaborations and aren't using the mocking as an aid to design. In fact the mock object is often simply there to replace a DOC so that we can simplify or speed up the test. This is at odds with the design technique that mockobjects.com and "Mock Roles, Not Objects" are recommending. As I understand it they view the outside-in process of design as being a big advantage of using interaction tests and use that to drive their designs (Need-Driven Development).

Its the second issue, how tests affect design, that interests me at the moment.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Saturday, January 19, 2008

TypeMock and Design

Roy Osherove has an interesting post on TypeMock/DI and design, it's a response to this post which is also interesting. In turn Jeremy Miller has put up his own response to Roy Osherove.

It's a well discussed topic and I've already put forward my views on it so I won't repeat them here but it is interesting that views on TypeMock are becoming more reasonable as time passes.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Thursday, January 17, 2008

Posting C# Code In Blogger

Gary Murchison was good enough to send me to the C# Code Format Website, John McDowall (another colleague) was good enough to work out that in order to get the content into Blogger correctly you need to either put all the content into one line (Notepad++ to the rescue) or switch "Convert line breaks" to false.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Wednesday, January 16, 2008

Interaction Testing of Service Collaborations

I decided to try to follow true interaction testing guidelines and use it as a design technique, specifically a technique to elicit roles and ISP compliant interfaces for DDD SERVICES.

At the minute I'm looking at how we can track changes to our domain objects so that we can report them (where appropriate) to external systems. We've decided to try using PostSharp, applying attributes to classes/members and the attributes will then cause the appropriate code to be inserted.

Interaction Test Driving The Initial Design
In my experience starting a large piece of work like this can be tricky. I've done some prototypes on using PostSharp and we basically know how we want the design to proceed.

To get me started though I need to write a high level test of this form, I decided to make it an interaction test and use TypeMock:

    [TestMethod]
    public void CanTrackCustomerActivation()
    {
        Customer customer = CustomerObjectMother.CreateProspect();
 
        DomainChangeMessage expectedMessage = new DomainChangeMessage(customer,
        "CustomerActivated");
 
        #region Mocking
 
        Mock serviceMock = MockManager.MockObject(typeof(IChangeTrackingService));
        serviceMock.ExpectCall("EventOccurred").Args(expectedMessage);
 
        IChangeTrackingService service = (IChangeTrackingService)serviceMock.MockedInstance;
 
        Mock serviceLocatorMock = MockManager.Mock(typeof(ServiceLocator), Constructor.Mocked);
        serviceLocatorMock.ExpectAndReturn("GetChangeTrackingService", service);
 
        #endregion
 
        customer.Activate();
 
        MockManager.Verify();
    } 

This test shows the following:
  1. We'll have a service of type IChangeTrackingService and we expect its EventOccurred method to be called.

  2. We expect the service to be retrieved from the existing ServiceLocator class (we considered using IoC but for now this will do, YAGNI).

Most importantly the test has helped us explore and confirm the design (see below) and although I'm not always made on interaction testing I think this one was useful.

To get the test pass all I need to do is put this sort of code into the Customer.ActivateMethod:

ServiceLocator.GetDomainChangeTrackingService().DomainEventOccurred(new DomainChangeMessage(this, "CustomerActivated"));

I'd refactor this code, but its a strarting point.

I need to make DomainChangeMessage a VALUE OBJECT to get this to pass (override Equals particularly). It was also nice that testing the changes I needed to make to DomainChangeMessage to turn it into a VALUE OBJECT (particularly overriding equals) was easy because I've written a helper class to deal with this in the past.

Importance Of The Test
In this case I'm happy that the test I created is very readable and shows clearly what the high level collaborations are.

The effect of this test on the design is subtle. I'd have designed this the same way regardless, the seperated interface (IChangeTrackingService) approach is one that works quite well and it's clear that DomainChangeMessage should be a VALUE OBJECT. However proving that this design is sound using an interaction test is valuable.

The next step is to write a test that actually checks that with a real instance of the SERVICE you get the correct behavior, which in this case might be just to save the DomainChangeMessage and make it available for use in the verification part of the test.

Oh but....
This is a bit of a cop out, every test that shows interaction testing uses it to get the role for a service style class.

What I'm really interested in is seeing how people use the same approach for domain ENTITIES, I'm not so sure that the ISP style interfaces you'd extract from them in order to get these tests to pass are so useful.

I'm prepared to be convinced though and the mock objects do seem to indicate that they think this approach can work for domain entities so I'm interested to see what they come up with.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Sunday, January 13, 2008

DDD with AOP and DI Presentation

A new DDD thread links to a talk about using AOP and DI to support DDD. The talk itself is very interesting, not sure I agree with all of it but it is good.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone