If you’ve never done Test Driven Development or aren’t even sure what this "crazy TDD stuff” is all about than this is the series for you. Over the next 30 days this series of posts take you from “I can spell TDD” to being able to consider yourself a “functional” TDD developer. Of course TDD is a very deep topic and truly mastering it will take quite a bit of time, but the rewards are well worth it. Along the way I’ll be showing you how tools like JustCode and JustMock can help you in your practice of TDD.

Previous Posts in this Series:  30 Days of TDD – Day 23 – Mocking… FROM THE FUTURE!

As I mentioned in my previous post, TDD is easy to do in a green field situation. However for most developers these types of projects are few and far between. Sometimes the brown field project we’re working on don’t lend themselves to unit testing. In the last post I demonstrated how Future Mocking can help in situations where mocking is difficult due to the use of statically bound dependencies. In this post I’ll show how using strict mocking can help ensure that you’re “after the fact” mocks of dependencies and methods are in line with how these components actually work.

 

Have You Met TED?

The practice of TDD is very clear on the concept of writing your tests before you write your code. Developers who do not start by writing tests, but write their unit tests after they’ve written the code under test are said to be practicing Test Eventually Development or TED. To be clear writing your tests before you write your code is clearly the preferred workflow. But, tests written after the code are better than no tests at all.

When you use TED you don’t have an opportunity to let your tests drive your design. This might seem like a minor point, but by letting my tests drive my design I’m able to be sure that my tests reflect the expected functionality of my code and I have a very low risk of any unknown side effects occurring when calling the various methods in my application. This enables me to use “loose mocking.” Loose mocking means that while I may arrange a mock in my test (even specifying how many times a method should be called and in which order the methods should be called) if I called a particular method or property or property that I did not arrange, the mock would be OK.

For example, consider this code:

 1:  public interface IMockMe
 2:     {
 3:  string Foo(int x, int y);
 4:  int Bar { get; set; }
 5:     }
 6:  
 7:     [TestFixture]
 8:  public class StrictAndLooseMocking
 9:     {
 10:         [Test]
 11:  public void LooseMocking()
 12:         {
 13:             var mockedInterface = Mock.Create<IMockMe>();
 14:             Mock.Arrange(() => mockedInterface.Foo(1, 2)).Returns("called!");
 15:  
 16:             var x = mockedInterface.Bar;
 17:             Assert.AreEqual(0, x);
 18:         }
 19:     }   

(get sample code)

One line one I have defined a simple interface called IMockMe. I also have a test called LooseMocking that starts on line 11. In the test I am arranging the Foo method of the IMockMe interface on line 14, but I am not creating an arrangement for the Bar property. On line 16 I am calling the Bar property. Even though I haven’t arranged this property the call still returns a value. This is a loosely typed mock. This means that I can call any method or property on this mock, even if I don’t have an arrangement for it. Additionally if I were to call Foo with a different parameter list than (1, 2) JustMock would still allow the call without making a fuss.

When I call a method or property that has not been arranged JustMock will return the default value for value types, an empty non-null string for type of string or a mock for a complex type or interface. This is the default behavior for JustMock and is referred to as “recursive loose.” This type of mocking is preferred by developers who practice TDD as it saves quite a bit of time when arranging mocks. JustMock also supports a “loose” mocking type, which returns nulls for non-value types.

Getting Strict

As mentioned, if you are doing TED, you probably do not want to use a lot of loose mocks. Loose mocks are great when you have let your tests drive your code design, but can hide a lot of unwanted side effects when you are writing unit tests for existing code. To help with this, JustMock supports strict mocking:

 1:         [Test]
 2:  public void StrictMocking()
 3:         {
 4:             var mockedInterface = Mock.Create<IMockMe>(Behavior.Strict);
 5:             Mock.Arrange(() => mockedInterface.Foo(1, 2)).Returns("called!");
 6:  
 7:             var x = mockedInterface.Bar;
 8:             Assert.AreEqual(0, x);
 9:         }

(get sample code)

In this test I’ve declared my mock of IMockMe as a strict mock by adding the Behavior.Strict flag as a parameter to the Mock.Create method on line four. This tells JustMock that I am creating a strict mock to fail the test if an unarranged call is made on my mock. If I run the test above, you can see that the test fails with an explanation that I have made a call to a member that was not arranged (Figure 1):

image

Figure 1 – We have a non-arranged member

This also extends to calls to Foo that are not arranged. If my test called Foo and passed one and two as the parameters, the test would pass. If I call Foo with any other parameter list JustMock would fail the test as there is no matching arrangement.

Summary

Hopefully you are in a situation where you can write your tests before your code. But if that’s not the case than any tests are better than none. If you don’t have the benefit of being able to let your tests drive your code design it’s important to make sure that your tests aren’t hiding problems by allowing unknown side effects. Strict mocking is a great tool to help you make sure that your tests are doing what you think they are doing and your code is working properly.

Continue the TDD journey:

JustMock banner


About the Author

James Bender

is a Developer and has been involved in software development and architecture for almost 20 years. He has built everything from small, single-user applications to Enterprise-scale, multi-user systems. His specialties are .NET development and architecture, TDD, Web Development, cloud computing, and agile development methodologies. James is a Microsoft MVP and the author of two books; "Professional Test Driven Development with C#" which was released in May of 2011 and "Windows 8 Apps with HTML5 and JavaScript" which will be available soon. James has a blog at JamesCBender.com and his Twitter ID is @JamesBender. Google Profile

Comments