Click here to monitor SSC
  • Av rating:
  • Total votes: 14
  • Total comments: 6
Michael Sorens

A TDD Journey: 2- Naming Tests; Mocking Frameworks; Dependency Injection

31 July 2014

Test-Driven Development (TDD) relies on the repetition of a very short development cycle Starting from  an initially failing automated test that defines the functionality that is required, and then producing the minimum amount of code to pass that test, and finally refactoring the new code. Michael Sorens continues his introduction to TDD that is more of a journey in six parts, by implementing the first tests and introducing the topics of Test Naming, Mocking Frameworks and Dependency Injection

Part 2: Naming Tests; Mocking Frameworks; Dependency Injection

 

Part 1: Trials and Tribulations of TDD

Part 2: Naming Tests; Mocking Frameworks; Dependency Injection

 

Part 3: Mocks vs. Stubs; Test Frameworks; Assertions; ReSharper Accelerators

 

Part 4: Tests as Documentation; False Positive Results; Component Isolation

 

Part 5: Tests vs. Code; Refactor Friendliness; Test Parameterization

 

Part 6: Mini-Factory Pattern; Don’t Care Terms

In part 1, I gave just enough background material on TDD so you could follow along on the TDD we are about to do. This and subsequent parts in this series will take you right inside my development environment so you can watch and participate as we develop a small component using TDD methods. So let’s get right to it!

The class we want to write is extremely simple but will serve to illustrate quite a number of useful points. To set the stage, say we have agreed on an API that provides a component called a WidgetActivator with a public method called Execute. Execute needs to prepare a widget for activation by loading and publishing its stuff. (We will refine just what “stuff” is later :-).

So where to begin? Refer back to part 1 which suggested thinking about behaviors rather than tests, and introduced Dan North’s list of key questions to use as a guide.

  1. Where to start?
  2. What to test/not to test?
  3. How much to put in one test?
  4. What to name a test?
  5. How to understand why a test fails?

To determine where to start (1) and what to test/not test (2), simply ask yourself:

What’s the next most important thing the system doesn’t do?

This question should yield some behavior “B”. Each behavior should be straightforward; simple. Start there, then repeat until you “run out of value” for the current task.

To determine how much to include in a test (3) and what to call it (4) write the behavior “B” as a sentence “S0”. If the sentence is too long or convoluted split it up into multiple sentences S0, S1, etc. How to tell if it is too long? If, for example, you have an “and” in there, e.g. “Converse should return an output and check a status” then it often—even usually—signifies that you are testing more than one behavior, so split it up. Each resultant sentence Sn names a test, quite literally. The convention I like to use is just to replace spaces in the sentence with underscores and perhaps omit non-essential connecting words for brevity. So if we have the sentence “Build method throws InvalidInputException when input is empty” the corresponding test name is just Build_throws_InvalidInputException_when_input_is_empty.

Test Naming

Now the content of these constructed sentences is not as freeform as it would appear. Every such sentence should follow this pattern:

<method> <behavior> <scenario>

…where you can think of <behavior> as answering what does it do? and <scenario> as answering under what conditions? Applying that to the sample sentence above:

[Build][_extracts_response][_when_input_is_nonempty]

For comparison, what might be considered the standard (propounded by the respected TDD authority, Roy Osherove, in his book The Art of Unit Testing) is <method><scenario><behavior>. That is more than just a re-ordering, though, as his approach is more a list of bullet points than a sentence. For his example of…

AnalyzeFile_FileWith3LinesAndFileProvider_ReadsFileUsingProvider

I mentally translate that to…

  • Analyze File
  • FileWith3LinesAndFileProvider
  • ReadsFileUsingProvider

…which I find harder to digest than the smooth flow of a sentence. Yes, you do have a clearer separation between method name, scenario, and behavior, but at the cost of legibility: it is harder to read a sentence with no visual separation between words.

So… as stated at the top of this section we want to create a WidgetActivator. It has an Execute method. And that method needs to delegate to a loader component to load the details of the widget. Our first behavior stated as a single sentence is then Execute delegates to IWidgetLoader to load the widget details. This sentence becomes the name of our first test. Let’s use TDD now to write a failing test then make it pass. I am going to emulate red-green-refactoring as we go. The test code shows up nominally with a red header bar because normally when you write the test code it is supposed to fail.

TEST: Write one line of code in the first test. We are testing a WidgetActivator (per the class name) so create one.

 

using NUnit.Framework;

 

namespace TddDemoTests

{

    public class WidgetActivatorTest

    {

        [Test]

        public void Execute_delegates_to_IWidgetLoader_to_load_widget_details()

        {

            var activator = new WidgetActivator();

        }

    }

Mocking Framework

For our next step, refer back to the test name: the WidgetActivator needs to delegate to an WidgetLoader, or perhaps more precisely stated, to an object that instantiates the WidgetLoader interface.

But in a unit test we want to stay focused on the class under test. We do not want an instance of an WidgetLoader that might go off and talk to a database; we want an instance that we have more fine-grained control over. So we are going to mock the object with moq, a mocking framework. (Of course, you can substitute your own favorite mocking framework if you so choose.)  Though moq is a powerful and flexible mocking framework, it is still quite easy to get started with. Here are some basics; you will see more later as needed.

Moq provides two useful syntaxes. First is Linq-to-Mocks. Yes, Microsoft’s Language Integrated Query, or LINQ, provides a wonderfully convenient mechanism for detailing what a mock needs to do. As a simple example, consider this:

var mockProvider = Mock.Of<IProvider>(p => p.Handles() == “string”);

Per the Linq-to-Mocks page I linked to above, the way to read this line is: from the universe of IProvider mocks, use one that returns string when its Handles() method is invoked. This Linq-to-Mocks syntax is quite handy, but not as rich as moq’s traditional imperative syntax. Essentially the same thing can be written imperatively like this:

var mockProvider = new Mock<IProvider>();

mockProvider.Setup(p => p.Handles()).Returns(“string”);

TEST: We next create the needed mock WidgetLoader. We are going to use moq’s traditional imperative syntax for this one; you will see why shortly.

using Moq;

using NUnit.Framework;

namespace TddDemoTests

{

    public class WidgetActivatorTest

    {

        [Test]

        public void Execute_delegates_to_IWidgetLoader_to_load_widget_details()

        {

            var mockWidgetLoader = new Mock<IWidgetLoader>();

            var activator = new WidgetActivator();

        }

    }

}

Notice the yellow highlighting above so you can quickly identify what has changed.

Next we need to supply the WidgetLoader mock to the WidgetActivator . But there are a variety of ways to do this. Should we pass the WidgetLoader to the Execute method? Should we give WidgetActivator a property with a setter method? Should the WidgetActivator constructor accept it? Remember that the test should drive the code construction, so the test itself should guide the design choice. It seems, then, that this test (by its name) is attempting to do too many things at once. Let’s rename it from Execute_delegates_to_IWidgetLoader_to_load_widget_details to  WidgetActivator_constructor_accepts_an_IWidgetLoader.

TEST: Wire the WidgetLoader to the WidgetActivator by Dependency Injection. (Note that we are passing in our mock loader, which is the Object property of mockWidgetLoader.)

using Moq;

using NUnit.Framework;

namespace TddDemoTests

{

    public class WidgetActivatorTest

    {

        [Test]

        public void WidgetActivator_constructor_accepts_an_IWidgetLoader()

        {

            var mockWidgetLoader = new Mock<IWidgetLoader>();

            var activator = new WidgetActivator(mockWidgetLoader.Object);

        }

    }

}

Dependency Injection

In this step all we did was pass a parameter to an object’s constructor. Simple, yes, but it actually introduces a powerful design pattern: dependency injection. When writing tests first, it is difficult not to use dependency injection; it flows naturally, almost automatically. But if you are not using TDD, and writing your production code first, DI can be neglected or overlooked. What is DI? James Shore in Dependency Injection Demystified states it best:

"Dependency Injection" is a 25-dollar term for a 5-cent concept… The Really Short Version: Dependency injection means giving an object its instance variables. Really. That's it.

The main benefits of using DI are:

  • Promotes loose coupling and therefore makes the code more maintainable.
  • Makes the application easier to test because, just as you see here, we can provide a mock object instead of a real one in the unit test.
  • Reduces and consolidates boilerplate code.

Let’s take a concrete example. On the left below, without dependency injection, MyWidget creates its own worker object, MyComponent. On the right the main program creates both a MyWidgetand a MyComponent object, then passes that MyComponent object to the MyWidgetobject. There are a few small changes inside the MyWidgetclass to accommodate this. The constructor now takes an argument and simply assigns the argument passed in to its private _MyComponent field. Also, note that _MyComponent is now of type IMyComponent instead of just MyComponent —the “I” prefix on the type name is a common convention that this is an interface. That adds extensibility and lets us, for example, create a test object that also implements IMyComponent and pass that in for testing purposes.

Without DI

With DI

static int Main(string[] args)

{

  var w = new MyWidget();

 

}

 

public MyWidget

{

  private MyComponent _myComponent;

 

  public MyWidget()

  {

   _myComponent = new MyComponent();

  }

}

 

static int Main(string[] args)

{

  var c = new MyComponent();

  var w = new MyWidget(c);

}

 

public MyWidget

{

  private IMyComponent _myComponent;

 

  public MyWidget(IMyComponent myComponent)

  {

   _myComponent = myComponent;

  }

}

 

In our WidgetActivatorTest class above test you saw how we injected a mock WidgetLoader into the WidgetActivator . What you will not see is how the production code injects a real WidgetLoader at runtime. In production code you should not be doing the injection manually as we have done in the test code or the sample above; rather you should use an IoC container. While IoC containers are beyond the scope of this article, I will provide a few useful links for further reading. Matthew Dennis itemizes the popular IoC Containers for the .NET world in Introduction to Munq IOC Container for ASP.NET (a third of the way or so down there is a nice chart showing relative performance of each). Scott Hanselman’s slightly older List of .NET Dependency Injection Containers is informative as well. Finally, Andrey Shchekin has published a detailed feature comparison of 19 different .NET IoC containers.

CODE: That completes the first test method which, as it stands, does not even compile. So we have, as we should, a failing test. Remember that failure can manifest as either failing to compile or, if compilable, then failing to pass. So now we turn to the production code, the class-under-test, to make the test pass.

 

using Moq;

using NUnit.Framework;

namespace TddDemoTests

{

    public class WidgetActivatorTest

    {

        [Test]

        public void WidgetActivator_constructor_accepts_an_IWidgetLoader()

        {

            var mockWidgetLoader = new Mock<IWidgetLoader>();

            var activator = new WidgetActivator(mockWidgetLoader.Object);

        }

    }

    public interface IWidgetLoader

    {

    }

 

    public class WidgetActivator

    {

        public WidgetActivator(IWidgetLoader widgetLoader)

        {

        }

    }

}

Implicit Assumptions 

We have now added the appropriate production code to allow the test to compile. Furthermore, if you execute the test you will see it passes. That is darn peculiar given the fact that we have not added any assertions yet! That is, a typical test concludes with an assertion to verify something, like the result was true, or the method returned a non-null object, or the string value was abc. But sometimes, like in this case, that assertion is implicit: as long as we can get to the end of the test method without throwing an exception it is a passing test. In this case, the implicit assertion is specifically that we could successfully create a WidgetActivator that accepts an WidgetLoader.

Now let’s return to our original first test: Execute_delegates_to_IWidgetLoader_to_load_widget_details.

TEST: The test name says we want to call the Execute method on our class. Then we add an explicit assertion to do what the test name asks for: to confirm that we called Load on the mock exactly one time. Here we use moq’s handy Verify method.

using Moq;

using NUnit.Framework;

namespace TddDemoTests

{

    public class WidgetActivatorTest

    {

        [Test]

        public void WidgetActivator_constructor_accepts_an_IWidgetLoader()

        {

            var mockWidgetLoader = new Mock<IWidgetLoader>();

            var activator = new WidgetActivator(mockWidgetLoader.Object);

        }

 

        [Test]

        public void Execute_delegates_to_IWidgetLoader_to_load_widget_details()

        {

            var mockWidgetLoader = new Mock<IWidgetLoader>();

            var activator = new WidgetActivator(mockWidgetLoader.Object);

 

            activator.Execute();

 

            mockWidgetLoader.Verify(x => x.Load(), Times.Once());

        }

    }

    public interface IWidgetLoader

    {

    }

    public class WidgetActivator

    {

        public WidgetActivator(IWidgetLoader widgetLoader)

        {

        }

    }

}

 

 

CODE: Make the code compile by adding the Execute method to the WidgetActivator class, and the Load method on the WidgetLoader interface.

 

using Moq;

using NUnit.Framework;

 

namespace TddDemoTests

{

    public class WidgetActivatorTest

    {

        [Test]

        public void WidgetActivator_constructor_accepts_an_IWidgetLoader()

        {

            var mockWidgetLoader = new Mock<IWidgetLoader>();

            var activator = new WidgetActivator(mockWidgetLoader.Object);

        }

 

        [Test]

        public void Execute_delegates_to_IWidgetLoader_to_load_widget_details()

        {

            var mockWidgetLoader = new Mock<IWidgetLoader>();

            var activator = new WidgetActivator(mockWidgetLoader.Object);

 

            activator.Execute();

 

            mockWidgetLoader.Verify(x => x.Load(), Times.Once());

        }

    }

 

   public interface IWidgetLoader

    {

        void Load();

    }

    public class WidgetActivator

    {

        public WidgetActivator(IWidgetLoader widgetLoader)

        {

        }

 

        public void Execute()

        {

        }

    }

}

That gives us a clean compile so the assertion runs… but it fails. Which is to say, the Load method is not being called exactly one time by the Execute method. In fact, it is not being called at all because the Execute method does not do anything yet. So add more code to get it to pass. The lines added here exactly mirror those you saw in the DI introduction earlier.

CODE:  Store the injected dependency in a local field so that we can then use it in subsequent methods.  

using Moq;

using NUnit.Framework;

namespace TddDemoTests

{

    public class WidgetActivatorTest

    {

        [Test]

        public void WidgetActivator_constructor_accepts_an_IWidgetLoader()

        {

            var mockWidgetLoader = new Mock<IWidgetLoader>();

            var activator = new WidgetActivator(mockWidgetLoader.Object);

        }

 

        [Test]

        public void Execute_delegates_to_IWidgetLoader_to_load_widget_details()

        {

            var mockWidgetLoader = new Mock<IWidgetLoader>();

            var activator = new WidgetActivator(mockWidgetLoader.Object);

 

            activator.Execute();

 

            mockWidgetLoader.Verify(x => x.Load(), Times.Once());

        }

    }

    public interface IWidgetLoader

    {

        void Load();

    }

    public class WidgetActivator

    {

        private readonly IWidgetLoader _widgetLoader;

        public WidgetActivator(IWidgetLoader widgetLoader)

        {

            _widgetLoader = widgetLoader;

        }

        public void Execute()

        {

            _widgetLoader.Load();

        }

    }

}

With those last bits, we are now invoking the Load method of WidgetLoader so we have completed the build-out of the test and just enough production code to make it pass.

Subsequent articles in this series will continue to interleave building real code with introducing new tools, concepts, and techniques to streamline the process. It is a long road yet ahead but my intent is to make your learning curve a gentle incline rather than a steep precipice, so by the time you finish you will be well-prepared to take the final leap (so to speak :-) to applying TDD to your own work!

Michael Sorens

Author profile:

Michael Sorens is passionate about software to be more productive, evidenced by his open source libraries in several languages (see his API bookshelf) as well as SqlDiffFramework (a DB comparison tool for heterogeneous systems including SQL Server, Oracle, and MySql). With degrees in computer science and engineering he has worked the gamut of companies from Fortune 500 firms to Silicon Valley startups over the last 25 years or so. Current passions include PowerShell, .NET, SQL, and XML technologies (see his full brand page). Spreading the seeds of good design wherever possible, he enjoys sharing knowledge via writing (see his full list of articles), teaching, and StackOverflow. Like what you have read? Connect with Michael on LinkedIn and Google +

Search for other articles by Michael Sorens

Rate this article:   Avg rating: from a total of 14 votes.


Poor

OK

Good

Great

Must read
Have Your Say
Do you have an opinion on this article? Then add your comment below:
You must be logged in to post to this forum

Click here to log in.


Subject: The three Rules?
Posted by: Karfau (not signed in)
Posted on: Saturday, August 9, 2014 at 11:38 PM
Message: I was just reading the first part, and there you talked about "Uncle Bob’s Three Laws".

I think you are violating them in the section "Mocking Framework", as you are adding code to your tests when it is already not compiling.

Could be that it is helpful for the readability of the article, but I think it should be pointed out.

Subject: duplication in test code?
Posted by: karfau (view profile)
Posted on: Saturday, August 9, 2014 at 11:55 PM
Message: Another question I have is:
Why is the extraction of the first test useful, as all the code in it is repeated in the second test.
So this part will be "tested twice" on each execution and
when this part fails (lets assume at runtime), there will just be two failing tests tests instead of one.

Subject: Re: the three rules?
Posted by: msorens (view profile)
Posted on: Monday, August 11, 2014 at 2:43 PM
Message: @karfau: Thanks for raising the question, but no, my code is *not* violating the three rules. But that is a common misconception (happened to me, too!).

When adding a new test, you do not stop as soon as it turns red; rather you stop when the test is completely written. Then you labor to make that test turn green by modfiying the class-under-test. Think about it this way: if you write a partial test then make it go green, you now have a passing test *that is wrong*. A test should be green if and only if it is valid.

If you take it to the extreme, it is even more evident: you questioned why I added more test code after adding a whole line of code that doesn't compile. But wouldn't your comment be equally valid after entering just one character that does not compile...? And it would be silly to go back and forth on every character to make it compile.

Subject: Re: the three rules?
Posted by: karfau (view profile)
Posted on: Monday, August 11, 2014 at 3:25 PM
Message: Hm, I don't agree with you in this point.
When reading the page you linked for the three rules from "Uncle Bob" and looking at the expamle steps that are provided there, I still understand them as I did before when asking my first question.

But I think it is not important to discuss this any further, as the most important thing is, the developer using it is in his "flow" with how he uses the rules.

I would rather like to hear what your answer to my second question about code duplication is. :)

Subject: Re: duplication in test code?
Posted by: msorens (view profile)
Posted on: Wednesday, August 13, 2014 at 1:34 PM
Message: Yes, once the second test is in place, the first test becomes completely redundant. But the fact that test one came *before* test two makes them both useful. To me, jumping right into the second test without having the first test would be doing too much all at once, because a failure in the second test could come from more than one cause. While it would be nice if any error would cause *exactly* one test to fail, that is not always practical; it is sufficient sometimes that an error cause *at least* one test to fail. (That said, in a later installment you will find that I recommend dropping a couple of these early tests...)

Subject: Thx
Posted by: karfau (view profile)
Posted on: Wednesday, August 13, 2014 at 1:43 PM
Message: Thx for the clarifications. (Yes I noticed the dropped tests in one of the follow up posts.)

 

Top Rated

Building a Customised ALM Platform with TFS and VSO
 The latest versions of Team Foundation Server are not only sophisticated, but extensible. Continue... Read more...

Rethinking the Practicalities of Recursion
 We all love recursion right up to the point of actually using it in production code. Why? Recursion... Read more...

Acceptance Testing with FitNesse: Multiplicities and Comparisons
 FitNesse is one of the most popular tools for unit testing since it is designed with a Wiki-style... Read more...

Acceptance Testing with FitNesse: Documentation and Infrastructure
 FitNesse is a popular general-purpose wiki-based framework for writing acceptance tests for software... Read more...

Prototyping Desktop Deblector
 Deblector is an open-source debugging add-in for .NET Reflector; the Reflector team investigated... Read more...

Most Viewed

A Complete URL Rewriting Solution for ASP.NET 2.0
 Ever wondered whether it's possible to create neater URLS, free of bulky Query String parameters?... Read more...

Visual Studio Setup - projects and custom actions
 This article describes the kinds of custom actions that can be used in your Visual Studio setup project. Read more...

.NET Application Architecture: the Data Access Layer
 Find out how to design a robust data access layer for your .NET applications. Read more...

Calling Cross Domain Web Services in AJAX
 The latest craze for mashups involves making cross-domain calls to Web Services from APIs made publicly... Read more...

10 Reasons Why Visual Basic is Better Than C#
 After having converted a whole lot of training materials based on VB.NET into C#, Andy ‘Wise Owl’ Brown... Read more...

Why Join

Over 400,000 Microsoft professionals subscribe to the Simple-Talk technical journal. Join today, it's fast, simple, free and secure.