Stop Designing for Testability – Revisited
I just received an email about a comment on my article on Code Project, Stop Designing for Testability. After nearly 3 years it is still getting comments.
The article is about the tension and balance between TDD/DI and OOD.
While looking at the article I am excited to see how much we have progressed, with the AAA syntax, thanks to .NET 3.5. Our recursive fakes and features that help lower the fragileness of our tests.
Unit Tests and Developers under Pressure
In TechEd 2008 David Platt interviewed Roy about the future of TDD. You should really view the Tech-Talk as Dave is really funny, although he does miss the number of possible TLA’s (which he recursively defines as a TLA = Three Letter Acronym) by 300.
About 5 minutes into the session David asks a key question: “What happens if your boss comes and says: I’m in a hurry, I need this, come on we need to ship this, we need to hurry up, forget about the tests“. What do you do?
I think that David has a valid point that is extremely important to address, as many teams are under pressure and they willing to find any excuses to ‘just code’. This question is going to define where we are going as a profession.
So what keeps us professional, what keeps us from doing cowboy development as Dave suggested that has been proven to lead us to more costs?
As Roy Said, it is a well defined process that will save ourselves from this pitfall, and writing unit tests is one of them. Just like professional teams will not even think of ditching their QA process, developer teams can not afford, in these economic times, to ditch unit testing. As a matter of fact, once you start unit testing you will find that you will be under less pressure!
You will spend some time writing tests (which you would have spent anyway on manually testing the application), but the ease at which you can continue to add functionality without breaking the code, will return that investment in no time. So the quickest way to implement a feature is actually using unit tests! I have seen so many teams make the mistake of not writing the tests, and within a few hours, they are already introducing bugs and are afraid to add features as they might (and probably will) break the code.
So back to Dave’s question, what happens if your boss is in a hurry? Be professional, just write the code and the tests as fast as you can. This is the most efficient way to write software.
The myth of integration tests
The question of what exactly is a unit test, is one that keeps on plaguing us as a community. I have heard many developers say “oh, no need to test that – its an integration test”.
Well – what is a unit test? and what is an integration test? Guess what: One programmer’s unit test is another’s integration test.
I have talked before about Microsoft getting it right when they called their developer testing tool msTest and not msUnit, and I am going to continue that line of thought. Most developers call any tests that is too complex to automate an Integration test. e.g. GUI or Database. The truth is once the right tools are in place and these ‘impossible to test’ will be possible, and once they are possible – they will be called unit-tests.
So all the tests that we can automate are unit-tests and those that are too complex to automate are integration tests. The complexity can come from brittleness of the tests – so when developing database applications – relying on the actual database will make our test brittle – i.e. Integration test.
We will see in time that with the right tools, we will have more areas that will be called unit tests, because testing them will become easy.
Unit Testing Collections
I have written about Lowering the friction of Unit testing, and how using Aspect Faking we can lower the friction of testing collections
The problem
Unit testing collections can be a bit tricky. Lets see some code and unit test this Sum() method:
public List<Salary> Salaries { get; } public float Sum() { float total = 0; foreach (var item in Salaries) { total += item.Value; } return total; }
public class Salary { public float Value { get; set; } ... }
Testing this can be simple: just supply a collection with fake items and run the code.
[TestMethod] public void Sum_Adds3Items() { var fakeSalaries = new List<Salary> { new Salary { Value = 5000 }, new Salary { Value = 6000 }, new Salary { Value = 5500 } }; var payments = new Payments(); payments.Salaries = fakeSalaries; Assert.AreEqual(16500, payments.Sum()); }
Simple, but in some cases, it is impossible to create the fake list. Examples are: Linq queries, SharePoints SPListCollection and SPItemCollection and DevExpress XPCollection. This are all custom collections and cannot be instantiated. We want to fake these collections, but we want to do it in a resilient way. Resilient enough that if we can choose to implementation via direct calls on the index without failing our tests.
public XpCollection<Salary> Salaries { get; set; } ... float total = 0; for (int i = 0; i<Salaries.Count; i++) { total += Salaries[i].Value; } return total;
Here is where Faking the Collection Aspect comes into play, we want to fake just the Collection-Aspect the XpCollection and swap it with a collection of our choice.
Isolate.Swap.CallsOn(payment.Salaries).WithCallsTo( new[] { new Salary { Value = 5000 }, new Salary { Value = 6000 }, new Salary { Value = 5500 } });
Now we can test our code and it won’t break if we change the implementation from using the enumerator of using direct access through the indexer.
Isolate.WhenCalled(() => payment.Salaries) .WillReturnCollectionValuesOf( new[] { new Salary { Value = 5000 }, new Salary { Value = 6000 }, new Salary { Value = 5500 } });
Once again, we manage to lower the friction of unit testing and create resilient tests.
Lowering the friction of Unit testing
At Typemock we have been learning allot about our customers lately and understanding where the friction is so that we can make unit testing even easier and maintainable.
What we are succeeding in doing is to lower the density of the tests (this means less code in each test) and raise the test resilient (this means the tests will still work after code changes)
Roy Oserove has talked about this (here, here and here). This has been the basis for the new API and concepts that we have already introduced in Typemock Isolator.
One feature that does this is the Recursive Fakes. Using this we fake and ignore a whole component, by faking a complete call stack. Our classic example is using SharePoint. In SharePoint a top most entry point is SPSite(). All other operations are a part of the call stack and objects returned from the SPSite.
example:
var site = new SPSite(); var web = site.OpenWeb(); var lists = web.Lists; var items = lists[1]; items[2].Update();
Note that SPSite is a Mother class of all other types.
We found out that in our tests, we normally don’t want to fail if any extra calls are called within this call stack. We also still want the test to pass if less calls are made within the call stack. Here is how we do it:
SPSite fakeSite = Isolate.Fake.Instance<SPSite>(Members.ReturnRecursiveFakes);
Using this will fake ALL the methods above, and all other methods that are called on the call stack of fakeSite! We can of course specify a fake value down the call stack:
Isolate.WhenCalled( () => fakeSite.OpenWeb().Lists[2].Items[1].Update). WillThrow(new Exception("");
Here we simulate an exception down the call stack, but all other calls will just work!
Thinking in the terms of Faking the call stack helps in writing less code in the test and adding to the resilient of the test. We are going to keep that trend as we continue to promote unit testing by enabling easy isolation.
Ruby Style Isolating – Aspect Faking
I have talked in the past about Ruby Style Isolating (Dynamically Typed), now it is part of the AAA syntax.
The big value of this feature is that you don’t have to inherit a type in order to replace it with a fake, the downfall of this is that when you refactor your code, you might fail the test.
There are many uses. One example is if you have a class without virtual methods, you can still overload it and swap the real type with the fake one.
This gives you testability strengths and the ability to keep your design intact.
Example Suppose we have the following class:
public class NiceClassWithoutVirtual { public int NonVirtualMethod() { return 30; // an example not virtual } }
Now we want to use a manual Stub to replace our NonVirtualMethod: we can do the following: note the new before the method.
public class FakeNiceClass: NiceClassWithoutVirtual { public new int NonVirtualMethod() { return 2; // our fake value in new not virtual method } }
We can use the Stub as follows
var real = new NiceClassWithoutVirtual(); var fake = new FakeNiceClass(); Isolate.Swap.CallsOn(real).WithCallsTo(fake);
All real.NonVirtualMethod() calls will be directed to fake.NonVirtualMethod()
Fake an Aspect
Note that any methods that are not defined in the swapped type will be run as normal. This allows ‘Aspects’ of the original class to be faked. It is possible to fake a group of methods that have a specific meaning, for example just the ISerializable aspect or just the IEnumerable aspect – so we can fake the collection behavior aspect of a type. This is exactly how we implemented the Swap-Collections Feature.
Future of Unit Testing and Economics
Euan Garden managed the PDC 2008 Panel Session on the Future of Unit Testing, and Andrew has made a short summary.
Unit Test => (Automated) Developers Tests
An interesting thought that come from listening to this panel is that there is a confusion about what unit tests are and I agree that we should really call it (Automated) Developers Tests. This is one of the cases where Microsoft got it right when they called their developer testing tool msTest and not msUnit. Even so, I will continue to call these unit tests, but my meaning is for all tests that developers need to do.
I also agree that many developers still have the concept of “I am a developer so I don’t need to test my code – that is something that the QA team should do”.
Two Futures…
Watching the panel it is obvious that there are two paths that are being considered. The first is that we should not use any tooling at all, and that the pain of doing unit tests will help us write better code – (if you have any pain – it means that you are writing bad code, if you keep on having pain perhaps you are not a good developer), while the other camp say that testing is boring/complex, lets make it easier with tooling
Developer Testing Economics
There is a lot of economic sense in making developers testing there code early on, the early you detect a bug the cheaper it is.
So even without creating a better designed software there is still great value in developers testing their code. The thing is that most developers are not willing to test their code, it is too painful/boring. The future is that more and more developers will unit test the code as it cuts the costs of developing software, and that unit testing will be an industry standard. But what is going to make these developers start testing their code?
The Future – Unit Testing will be industry standard
I follow the Rails mantras of Opinionated Software, and my opinion is that we have to make unit testing easier for the masses to follow. It is great to see that Microsoft is also investing in tooling (Pex and TDD in Visual Studio 2010. Other vendors have these tools already – Parasoft .TEST).
The biggest obstacle for developers to unit tests is the need to isolate the code under test. Software is complex, which makes testing it complex. Using the divide and conquer technique to reduce the complexity of the tested unit will render testing these units simple.
Mocking frameworks today are not the same tooling they used to be, they are now isolation tools and these isolation tools will keep developing and progress and help developers focus on simplifying the task of testing their code.
Mocking frameworks – dream feature
There are some developers SHOUTING, that mocking static and non-virtual methods is a big No-No. Roy, is calling them dogmatic.
Come on guys, the most requested feature from Rhino.Mocks is the ability to mock non-virtual and static members, and Oren has even implemented these when possible (MarshalByRef Objects). I am sure that if it was easy, Daniel would do so too.
In other languages where objects can be swapped without Dependency Injection, there is no-one, calling these features – Bad Practice, just the opposite. They are called ‘Power features’, because that is what they are.
You might prefer to sweat and spend a lot of your time figuring out how to make your code testable, and you might find it easier in your company to introduce a free tool, but please, don’t call a tool that gives you lot of pain, forces you to use DI (even if you don’t really need it) and to spend time creating utterly useless wrappers – a feature!
Interesting Unit Testing Survay
According to a Telerik Survey (brought to me by Avi Kaye) Unit Testing is still not mainstream.

I am not sure how many people voted, and although the result might surprise some of you, these results confirm what I think about the implementation of automated unit tests.
Unit testing is still quite difficult and there is a need for better tools to help with the pain.
Understanding Mock Objects – Better Design
Azam has written a post about Ben Hall’s article “Beginning to Mock Using Rhino Mocks and MbUnit“. The logic in the example is a method that returns an image of the sun in the day and the moon at night. In both Azam’s and Ben Halls examples, the GetImage()method returns the image name
public string GetImage() { int currentHour = DateTime.Now.Hour; if (currentHour > 6 && currentHour < 21) return "sun.jpg"; else return "moon.jpg"; }
Using Interface only Mocking Frameworks will lead to redesigning this in order for the code to be testable and extracting and wrapping ‘DateTime.Now’ to an interface and concrete class:
public interface IDateTime { int GetHour(); } public class DateTimeController : IDateTime { public int GetHour() { return DateTime.Now.Hour; } } public class ImageManagement { public string GetImage(IDateTime time) { int currentHour = time.GetHour(); if (currentHour > 6 && currentHour < 21) return "sun.jpg"; else return "moon.jpg"; } }
Scott Bellware has suggested a better design – and that is to move the ‘is it day or night’ logic from the ImageManagement class to the IDateTime
The calculation of whether it is day or night is an orthogonal concern of the image generation and therefore should be moved out of the GetImage method.
Now our code will look at following:
public interface ITimeService { public bool IsDayTime(DateTime time) } public class ConcreteTimeService : ITimeService { public int IsDayTime(DateTime time) { int currentHour = time.GetHour(); return (currentHour > 6 && currentHour < 21) ; } } public class ImageManagement { public static string GetImage(ITimeService time) { if (time.IsDayTime(DateTime.Now)) return "sun.jpg"; else return "moon.jpg"; } }
The first thing to note is that being forced to use interfaces and Dependency Injection (the first example) did not naturally lead to a good design – there is still a need to think about the design in classical – old fashion – Object Oriented terms.
But if we are thinking about designing in the old fashioned way, here is another approach to reach the same (or better) results: using extension methods, which is a much more natural way of doing this in .NET 3.0+
public static class DateTimeExtensions { public static bool IsDayTime(this DateTime time) { int currentHour = time.GetHour(); return (currentHour > 6 && currentHour < 21) ; } } public class ImageManagement { public static string GetImage() { if (DateTime.Now.IsDayTime()) return "sun.jpg"; else return "moon.jpg"; } }
This makes more sense as we are extending the abilities of DateTime, the code is easy to read and understand. The only problem is how do we test this code.
Well it is simple with Typemock Isolator here is how:
[Test,ClearMocks] public void WhenItIsDayTime_ReturnSunImage() { // pretend it is always day using (RecordExpectations r = RecorderManager.StartRecording()) { r.ExpectAndReturn( DateTime.Now.IsDayTime, true); } Assert.AreEqual("sun.jpg", ImageManagement.GetImage()); }
So here are two points to think about:
- You must always think about your design, using IoC and DI does not automatically lead to better designs
- If you are already thinking about your design, you might as well have the freedom to develop the design you reached, without limitations of your tools
Recent Posts
- Unacceptable: Unit testing will take 20 years to catch on
- The 4 reasons why we DIDN’T choose Oslo
- Typemock Academy Launch
- The First Rule to Software Craftsmanship
- Goal-driven Development
Categories
- .NET Tests
- Agile
- Code Integrity
- Community
- Debugging
- Fun
- Management for Geeks
- Marketing
- Product
- Release
- Reviews
- SharePoint
- TDD
- Time Management
- Uncategorized
- Unit Tests
Archives
- May 2010
- April 2010
- March 2010
- February 2010
- December 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- December 2008
- November 2008
- August 2008
- July 2008
- May 2008
- April 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006

