Test Fakes – Solving a Domain Entity Issue

Follow on from :Testing with Domain Driven Design

Background on the design in question

  • We are using NHibernate for persistence on Oracle.
  • We have service that accept command that are coarse grained and perform a clearly defined business function, they are not chatty services.
  • We are using the notion of aggregate roots so all child objects are created and managed by the owning aggregate root. If you need to access the child it must be done via the AR
  • The domain is relatively large and complex.

Background problem

We had issues where we were dealing with domain objects in test and getting problems with interrogating child collections. For example we sometimes need to be able to update a child of an aggregate root and we were using the id of the child (within our command object) to indicate which child to update. We are using a basic database identity field (oracle sequence) for setting the ids on all of our user defined entities.
Herein lies our problem;* In our test we create an aggregate root complete with child objects. We then want to test, for example, updating a child of the aggregate root via a DTO based command (i.e. using an id to define the child to update) and we run into issues when all of the child object have the same id of 0 as they are not persisted (it’s a unit test). Now this would never happen in real life. Why would you issue a command to update something that has not been persisted, how do you even know about that object?
The quick solution that I have seen used a lot is to set the ids of all of the domain objects prior to running the test. I don’t like this if you are doing this by exposing the ID setter on the domain object. This is opening up the API of our domain for testability and is potentially the start of a slippery slope in to a pit of hell. An easy way around this is to use fakes. These object are just child object of the domain objects in question that help expose stuff the domain shouldn’t; in this case the ID setter.
The other alternative is to set the id on creation of the fake so the setter of the id is not exposed. This can also work but it will mean your fake will always have an id set. For the situation I was in this was not suitable.

The end solution

All domain objects have a fake create for it. All of the fake implement an interface ISettableId. This interface is defined as below:

**CODE GOES HERE**

public interface ISettableId
{
bool HasIdBeenSet();
void SetId(TId id);
}

With an implementation example (its id type is and integer) :

public class FooFake : Foo, ISettableId
{
public FooFake(string name, TypeRequiredForValidConstruction myDependecy)
: base(name, myDependecy)
{}
public bool HasIdBeenSet()
{
return _id != 0;
}
public void SetId(int id)
{
_id = id;
}
}

This mean we can now create fake objects and emulate persistence later by reflecting down the object graph and setting all of the ids. This is much faster than hitting the database and has proved to be a very valid exercise as we can now run tests again transient and persisted versions of the object graph without having a db connection.
One additional thing I should mention is that the creation of child object now must be exposed as a hook. For example when we create child objects I do not just new up to object and add it to a collection. I call a protected virtual method that creates the child object and then add that to the list. This allows my fake to override the return type that is added to the list so children can also be fakes. This has not increased the exposure of the domain but has now facilitate a hook to allow me to create fakes for my child collection.

Caveats:

Fakes should not include any logic. The fakes I am using only allow the setting of ids. The only logic they have is to check whether the id is set (this allows us to skip objects that have had their ids set when we walk the object graph and not go around in circles). The only other methods that are required is the overrides of the creation of child objects.
Other methods you may find in the fakes are builder methods. Instead of having big factories for creating test object you may choose to put the object creation closer to the owner by putting it in the fake class itself.

Summary

As I mentioned, we have a pretty large and complex domain we were running into issues where the difference between persisted and non persisted objects graphs was becoming problematic; using the fakes has allowed us to keep the domain clean and only as open as possible while allowing us to emulate persistence without the cost of hitting a database. Over all I’m pretty happy with the result.

*I’m sure there are other way to solve this higher level problem

Testing with Domian Driven Design

DDD is a hairy beast. It feels like everyone has a slightly different opinion of what it is. I personally thought I had a pretty good grasp on it until I caught up with Udi Dahan earlier this year where he (as per usual) completely turn my understanding on its head.
That being said I believe the way I am approaching the current project is in line with what I believe the majority of people believe DDD is, correctly or otherwise.
Key aspects in this project that help make it resemble a DDD domain are:

  • The level of understanding the devs have and the ubiquitous language that is in use and they way it is constantly evolving amoungts all team memebers, including our SMEs/Users
  • The general structure of the code – repositories, services, aggregate roots comprised of entities and value types etc etc

To be honest one could argue, that like most DDD projects, it is just clean OO coding. It is; that doesn’t mean that there isn’t something that others could glean of of the project, such as what we are doing to keep things clean and help with creating nice tests.

First and foremost follow TDD and BDD if possible
If you have a good understanding of the component you are building then writing explicit specifications should be easy. Do this with your BA and SME make sure the tests are not shallow low value tests. Investigate what BDD is and see if one of the many framework fit your teams needs. Personally I am still using xUnit frameworks and am creating elaborate contexts on which I make assertions. My fixture set ups can sometimes be complex but my test methods are very clear & clean and can often just be one line assert statements. I have not found a BDD framework that sits well with me in the .Net world like Cucumber does in my Rails development, so I will continue down this path till I find something I like better than explicit and somewhat elaborate xUnit styled tests.

The domain should remain as pure as humanly possibly
Anything that is public should have a good reason for being so. Unfortunately most developers use public as their default. This is bad practice as it produces a very non intuitive API. Use access to help show the other developers how you intended the API to be used.
Typically, IMO, this means protected virtual by default. (I’m an NH fanboi). Also restrict what you return. I personally don’t like the idea of returning child entities from parent entities especially aggregate roots. What is the consumer going to do with these entities? Most of the time a value type or projection is more appropriate and helps keep the line of ownership clean.

Modifying the domain to be more testable should be frowned upon, especially if it confused the API
This ties into the first point. NB : There are concession that I make that I can live with (I will cover them soon) but I believe these do not negatively affect my domain and make life easier and my intentions more explicit to the next developer

Use subclass fakes to increase accessibility for testing
I often see people making fields, properties or methods public so tests can call them. Please don’t do this. If these are private definitely do not expose them. This is an indication that you are not doing TDD. Private methods generally only come from refactoring once your test pass so testing private methods is a sure sign you are not doing TDD. Internals sometimes may warrant being tested. This is OK as we can make internals visible to the test project. I generally don’t mind doing this as I put this in the AssemblyInfo file which is recreated in my deployment anyway so there is no dodgy test orientated code in my final deployed assembly. I must say that I don’t really do this a lot and i think people use this as a crutch. True TDD generally will not warrant a lot of this, However i find myself doing it a bit in my domain, possibly out of fear more than any really rational reason.
If you really need to make something accessible to test and don’t want to expose it fully then create a fake that inherits from the class and override the accessor in that class. Sometimes I do this to check things like IDs. Again question whether this is really needed, have faith in the TDD process!

Allow hooks in the domain for creating child objects
One thing I have used in the current project is protected factory method to create child entities. By opening up these one liners I can override the method in a fake sub class to create a fake subclass of the child: eg OrderFake will create and return an OrderLineFake in its CreateOrderLine method as opposed to the Order creating and returning an OrderLine in its CreateOrderLine.

When using fakes of real domain objects make sure you are not hiding any of the real object functionality. The fakes should be as plain as possible. Adding additional logic will surely corrupt your tests. One thing to watch for is to make sure your fakes implement the same ctors as their parent and call into those ctors. Failure to do this will create a big PITA 🙂

Next post I will talk about some issues and traps that we as a team have managed to fall into. Most of them have been things when consciously question know we shouldn’t do but have managed to creep into the solution, hopefully we can help you avoid repeating our mistakes!

What is Regression Testing?

We are on a journey. The company I work for is a very large one and has suffered some lag in migrating to modern ways of software development, a situation many companies of this size often find themselves in. Fortunately the team I work with have come together to make a conscious and consistent effort to improve our area of influence. First and foremost was the introduction of a structured developer oriented testing plan. Because we are a development team we started with unit testing, integration testing and some build scripts to run these tests. From there we have improved they way we do those tests, streamlined our scripts and made CI a solid part of our process. Automated deployments have become easier too leading to automated staged deployments. We are now at the stage where we are adding in Fitness and UI testing to the equation.

Each of these step have been driven from the ground up. We have had to, carefully, maneuver these processes into our daily process and show the benefits to management. It has taken time but they have responded very well; so well that they are jumping on board! This is a great thing and has made all the hard work, and it was hard work, worthwhile.
However there are still political games to play. The language is fractured and management want to throw around terms that they don’t really understand and force their idea of these terms onto the very people that introduced them to the department, sound familiar? 😉

“Unit Testing” and “Regression Testing” are two of the terms du jour. Unit testing “means” something a developer does and regression testing is an automated UI test that a non techie can watch as it magically clicks away at the screen. This, as you may know, is not correct… well not strictly correct; and in a place where the language is so commonly fractured it is hard to justify fighting for seemingly such trivial victories.
So instead I vent here.

The things that i felt i needed to express most importantly are:
Any automated test is a regression test
– and –
You do not write regression tests.
What i am referring to in that last statement is merely the fact that you write a repeatable test that tests a certain unit, module or scenario, that can be automated and then your check it in to source control. The very notion that it is part of your build process/continuous integration means it now acts as a regression test.
So our tests that

  • Test a unit, i.e. an xUnit framework which may also uses mocks and stubs etc
  • Testing seams or integration points i.e. DB tests, file systems tests, web service tests etc
  • System smoke test
  • High level acceptance tests using tools like cucumber, fitness etc
  • UI testing – i.e. a button clicking framework like QTP

are all regression test because the are repeatable, automated tests.
Please don’t make the mistake of thinking you will explicitly write a regression test. The test should test that the code produces a specific outcome e.g. enforces a business rule.
The automation and maintenance of a healthy CI environment makes those tests regression tests.

I guess the key here is really your CI process. If the tests can be dodged or accidentally not run somehow then this will need to be addressed.
Make the pit of success an easy one for you team to fall in to and let them know regression tests are a side effect of good daily habits.

Coding Guidelines

Last night I presented to the Perth .Net Community on an upcoming tool called PEX. There were a couple of mentions in the talk of “allowable exceptions” backed up by mentions of the .Net Framework Guidelines.
I was asked by a few people afterward what the book was and whether I had presumably made these guidelines up 😉
I was under the impression that this book was widely read, so it is clearly not as common knowledge as i may have thought.
Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (2nd Edition)
is a must read for .Net devs that are writing code that is consumable by others (ie anything that uses public or protected accessors)

I would highly recommend this as it also gives a lot of background as to “why” behind the recommendations. It is also nice to read the comment from authors of certain .Net framework as they point out many things including their mistakes.

The books is made available online for free (not sure if it is in its entirety) at MSDN here

The allowable exception was in reference to section 7.3.5 (page 237) or a cut down version here

Oh, the links to the Pex stuff are here:

Thanks to everyone who came (especially those who bought beers afterwards) 😉

Manning Book Reviews

Thought i’d let you guys know of some books i have been reading that are pretty good, They are all from Manning which I am really starting to like that publisher more and more.

JQuery In Action: Within about 90 minutes of reading this book you will understand the fundamentals of jQuery and be ready to do basic, but powerful, jQuery code. If you are using javascript natively seriously consider switching to jQuery and get this book. jQuery also has a test framework (QUnit) and a great suite of UI plugins (jQuery UI)

Art Of Unit Testing: Easily the best unit testing book I have read (and I have read a few). Great for newbies and those still getting to grips with how to test anything more than the most trivial of examples. It is the book i would recommend to people looking to learn to do TDD well. Note the examples are in C# but they really dont require indepth knowledge of .Net, in the same way all the other books are in java and I havent written a line of a coffee flavoured code in a decade. In saying that the tools are all .Net based but i am sure there are Python, Ruby and Java equivilents avaliable for most.

NHibernate in Action: Pretty much the same as the Hibernate book but shows all the .Net stuff you can do. its also a bit more up to date that the original Hibernate book (which has since had a second release). .Net devs nusing NH need* this book.

IronPython in Action: not a bad book… it does exactly what it intends, it teaches .Net devs about python on the CLR. The question is: Do you care? For me it was something of interest, i doubt I’ll ever use it in production. As a side note for the .Net kids i think the path of C# => Boo => Python =>Ruby is the one to take for the typical C# developer**. It keeps the “barrier to entry” low for the next step so you are picking up one new thing at a time (ie new syntax, dynamic language contrainst, DSLs and other scripty weirdness) and by the end of the process you have 4 languages under your belt in about the same time it would take to do the C# => Ruby jump.

that’s all

Rhys

*OK no one needs anything, especially as the NH doc a pretty good, but you will be severely hindered without it.
** VB.Net devs; you know you will never learn another language, you have had years to do so!

MS test… why?

*I am talking about MS test and Vs 2005… i havenot used 2008 so cant comment*
I really am struggling to see the benefits of MS test suite over the OSS equivalents. NUnit which is as old as the hills has been my right hand man for a couple of years now, I have dabbled in MBUnit and ashamedly have not even used xUnit for even one project (now on the to do list!). Unfortunately these have only been on my solo or PoC projects. As i work in .Net companies the fixation of TFS and the MS suite of tools linger.. no matter what country you are in.
The ease of use of some thing like NUnit compared to MS test is not at first apparent then you use both of them…
Both integrate with TD.Net and ReSharper… and i think that’s where they stop. If you don’t use either of those tools (you should if you are attempting to be TDD) then MS test may appear to be less friction as you can run the test from within VS. This is an illusion!
I personally think the NUnit test GUI is faster and nicer to use as i can see everything at a glance and my whole solution is not required to be rebuilt very time i want to run a test (Arrrrrgggh!)
Take for example the graphical representation of your tests:
Firstly NUnit Gui:

versus the test view in VS


The test view in VS only really tells me that I have tests. Well, I know that because I wrote them, where are my test failing? Is it all in one namespace? One class? One category? Who knows. Sure you can filter but the intuitive aspect of the node view NUnit offers, give me the instant feedback that, to me, is worthwhile.
As most of us write more the 30 test having a window with one column showing all test is a little silly. It also shows all test for the whole solution….

Most importantly running units test as part of the build process with NUnit is trivial. I use NAnt at home and MSbuild at work. Getting NUnit to run as part of a build process was trivial.. can the same be sad for MSTest… no. Can it be done? Sure, I guess so, but I will never find out because I have better things to do then bend and mold software to fit my ridiculously simple requirements, I would rather just use the software that works as it should.

If you are using MS test I would strongly recommend rethinking that descision. I dont think you can be effectively Test Driven with that tool set so get a tool set that help you not hinders.

"Just one test!"

I have read in a couple of places now (amongst other generalities) that a unit test per method is the standard “rule of thumb”. I have been surprised at this. I understand that at least one test per real method (not one line getter/setters) is a minimum but to generalise it to only one is a bit odd.
This was kinda sparked off by this post http://blog.sidu.in/2007/06/pre-run-tasks-unit-testing-anti-pattern.html. I am not coming down on the poster at all and I may have over reacted to an aspect of the post that was certainly not the main point of the thread.
But just one test per method? It got me thinking.
I generally have a test to cover each of the paths in the method (to an extent).
I never really thought about it but I guess complete coverage* would come from tests that match each of the paths and therefore the cyclomatic complexity of that method. If you have an increasing number of tests for a method you may want to reconsider the functionality of the method. Can it be refactored?
This I believe is another benefit of TDD. It forces you to think about function design first not just start the torrent of code and hope that what comes out works. This is also a reason to write the tests first. I find it amusing that some still write the test after they write the code. I mean really, why not define what you want then build it.

* no im not a coverage nazi :p

TDD still not with the masses?

Recently I have been a contractor on a project that I have been given I little bit of grief (perhaps light heart, perhaps not) regarding the number of unit tests I have written in comparison to the production code I have submitted. Upon talking to some external mates in the development field there still seems to be some confusion as to why to test, how to test and when to test. I will happily admit that I am no TDD guru and am relatively new to the having only really being diligent about unit tests over the last year or so.

I did want to share some of my reasons, that may not be so text book, for using TDD. I will start with aspects of TDD, that on my most recent project, I have directly benefited from:

Define the Functionality of the Module
In the last project requirements were somewhat lose, so writing the unit test help the guy with the business know how and myself knuckle out what exactly we wanted these blocks of code to do. The people that will have to maintain my code as I move to the next project will probably find this module easier to maintain because of the reasonably well named and documented tests that are in place, meaning reduced ongoing cost of the code base.

Ability to Refactor with Confidence
As I was receiving information about the requirements in a piecemeal fashion, I was forced to write code for the functionality as I got it. This quickly became quite a large amount of code which later we found had aspects replicated across multiple classes. Refactoring these classes to strategies that inherited from a base strategy which inturn implemented an interface with the real business logic held in a handful of delegates meant we reduced the lines of code by 73%. As we refactored we made sure the entire block of unit tests still passed. The code is now a fraction of the size, very easy to read and maintain, fast and still fulfils the requirement set forth by the business. Refactoring all that code that took weeks to write was done in a day, in confidence because the unit tests were written up front.

Reduction of “Gold Plating”
In some case I get carried away and start writing things that I haven’t got a test for, because they may be needed in the future. This is by and large a bad habit of mine, I don’t get paid to gold plate, I get paid to provide a quality solution to a defined problem, even if that problem is not very well defined!
How has TDD helped? If it was not being covered by a unit test, it either needs to be or it gets removed. 9/10 it get removed as the tests are written first and they define the functionality.

Code Confidence
Although test don’t prove you code is good (see TDD Anti Patterns) it odes show that I have thought about what I am doing and give other developers or interested parties a direct view at what my code does. Most of my test methods are named so it is pretty obvious what they do, sure some get pretty long but I can find a unit for a module that I wrote months ago pretty bloody quick and figure out with in seconds the exact functionality. This is especially helpful if you have no BA support or business requirement documentation (yes it happens). Not only am I more confident in my code but I am more confident in other code if it is unit tested.

Encourages Correct Separation of Concerns
Especially when using mocks it becomes apparent when projects are starting to take on more functionality than they should.

Up-to-date Code
As I am writing tests for my code, as I go, I find that I am more likely to be within minutes of a previous compiling working solution. Formerly I used to go on tangents and write pages of code which may have been in a state far removed from a submittable state. If for some reason I was asked to shift on to other functionality I would have to shelve changes roll back and then work on something else. If I ever cmame back to that code I often had no idea where I was up to. Now I know exactly where I am up to… the method that breaks the unit tests! It is also more likely that I wouldn’t have to shelve as it is probably only a minute away from being in a compilable stae that I could check in to source control.

Easier to Make Changes
There have been some instances where the business requirements, or my understanding of them have been (a little bit) off. Having the test there means I can modify the test to assert correct assumption run the tests, see it fails and then make an isolated change in the code. As the test marry up nicely to the code the place where the change is required is very easily found and fix. ..Run test…. Pass test… Check in.

So how do i go about it? Well my”why” is covered above. For more reason check out http://www.testdriven.com or any other of the plethora of sites and books dedicated to TDD… as for the when and how…

When to test?
Before you have even written the functionality! Define what you want the method to achieve. You will probably find your self writing multiple tests per method and test fixtures are generally a lot larger than the class they test, bu the time you save in reduced debugging time and easier maintenance is well worth it.

How to test?
There are heaps of tools to use and can be a personal thing. Currently I am using TestDriven.Net with NCover and NUnit as well as ReSharper & Rhino mocks. As ReSharper is the only tool here I have paid for there is no reason not to get these widely used tools (I probably should throw some money at Testdriven.net).
Try to get a test project for each business project and a test fixtures should closely marry up with the projects classes. I don’t test minor thing like properties… there should be reason for the test!

Most frameworks now are very open to TDD, so there is very little reason not to use it. Right up to UI patterns, all but the view are very easy to test and mock. And as the view is completely stupid it should not have a lot scope for error.
So start testing; the initial growing pains are well worth it.

RhysC

Rhino Mocks

CDS showed me a cool new tool today called Rhino Mocks. I have never used mocks before so was impressed nonetheless. Its helping make unit test actual unit test and not block of code that hit DB’s or file systems or this, that and the next thing (check out Micheal Feathers post re unit test rules here).
One of the coolest thing is it is written by an up and coming software geek who is only 24 and has a healthy list of accomplishments already. Check out the work of Oren Eini (AKA Ayende Rahien) here