Click here to monitor SSC
  • Av rating:
  • Total votes: 10
  • Total comments: 0
Michael Sorens

A TDD Journey: 3- Mocks vs. Stubs; Test Frameworks; Assertions; ReSharper Accelerators

01 August 2014

Test-Driven Development (TDD) involves the repetition of a very short development cycle that begins with an initially-failing test that defines the required functionality, and ends with 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 doubles; Test Runners, Constraints and assertions.

 

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

This is part 3 of our exploration into practicing hands-on TDD. Unlike most of my multi-part series, it is not advisable to join this one in the middle. So if you are arriving fresh, please go back and review part 1 (a short introduction to TDD reasons and methods) and part 2 (implementing the first tests) before proceeding.

The code to date is shown immediately below. Points to review:

  • WidgetActivator is the class-under-test.
  • The WidgetActivator needs both a loader and a publisher to do its work.
  • The first test verifies that the loader is wired up correctly in the form of an WidgetLoader. Using an interface for the type makes it easy to swap in a testing version (a mock) of a WidgetLoader in the test shown, whereas production code will use a genuine WidgetLoader.
  • The second test verifies that the WidgetActivator uses its WidgetLoader to do something.
  • The moq mocking framework lets you check if a particular method was called on the mock with moq’s 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

    {

        void Load();

    }

    public class WidgetActivator

    {

        private readonly IWidgetLoader _widgetLoader;

        public WidgetActivator(IWidgetLoader widgetLoader)

        {

            _widgetLoader = widgetLoader;

        }

        public void Execute()

        {

            _widgetLoader.Load();

        }

    }

}

Now we introduce the IWidgetPublisher , which is analogous to the WidgetLoader. In the interests of brevity, from this point forward I am only going to show the relevant portions of the code rather than showing everything. So here we go!

TEST: Again start by creating a WidgetActivator . To compile we must supply an WidgetLoader argument. But this test does not care about an WidgetLoader so we use a stub for that. (Notice that when we pass in a stub, there is no final “.Object”, like we had to use with the mock object in the previous test.)

[Test]

public void WidgetActivator_constructor_accepts_an_IWidgetPublisher()

{

    var stubWidgetLoader = Mock.Of<IWidgetLoader>();

    var activator = new WidgetActivator(stubWidgetLoader);

}

 

Test Doubles

Here you see the notion of a stub mentioned in the commentary—and reflected in the variable name—yet it is still using the Mock class. The reason is that moq handles stubs as well as mocks. In part 2, you saw that moq provides two syntax choices to create mock objects: the Linq-to-Mocks approach, which is better suited for stubs and the traditional imperative syntax, which is better suited for mocks. Mocks and stubs are both more broadly described as test doubles, a term coined by Gerard Meszaros in his book xUnit Patterns. A test double is simply a test objects used in place of a real object in a test. On his web site, Meszaros has a detailed chart comparing and contrasting mocks and stubs, along with fakes and dummies in (what an eponymous coincidence!) a section entitled Mocks, Fakes, Stubs, and Dummies. Unfortunately, he quickly reveals that the nomenclature is haphazard at best, with different authors using different terms: a stub is sometimes called a mock, a dummy is sometimes called a stub (but at least a mock is always a mock :-). I mention that only so that as you do further reading on your own you are prepared to pay less attention to the names and more to the substance.

Briefly then, here is a good summary of mocks, fakes, stubs, and dummies according to Meszaros interpreted by Martin Fowler in Mocks Aren’t Stubs because he says it so well:

  • Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
  • Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in-memory database is a good example).
  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test…
  • Mocks are… objects pre-programmed with expectations [that] form a specification of the calls they are expected to receive.

TEST: As I said, we do not care in this test about the loader so we used a stub. What we do care about is an IWidgetPublisher so let’s add a mock rather than a stub, just as we did in the first test, and also pass it to the WidgetActivator  constructor.

 [Test]

public void WidgetActivator_constructor_accepts_an_IWidgetPublisher()

{

    var mockWidgetPublisher = new Mock<IWidgetPublisher>();

    var stubWidgetLoader = Mock.Of<IWidgetLoader>();

    var activator = new WidgetActivator(stubWidgetLoader, mockWidgetPublisher.Object);

}

Generally speaking, I prefer to use the Mock-to-Linq syntax (i.e. Mock.Of<type>) for stubs and moq’s traditional syntax (new Mock<type>) for mocks as you see above. There is a lot of overlap in the capabilities of the two, so that rule is by convention not by necessity. I particularly like it, though, because anyone reading my tests will know which test doubles are important for a given test—the mocks rather than the stubs.

CODE: That completes the test; now we work on getting the production code to compile and the test to pass. This new test is quite analogous to the earlier WidgetLoader test, except now we need a two-argument constructor for WidgetActivator . But first, let’s add the new required interface.

public interface IWidgetPublisher

{

}

A constructor change is one of many rote tasks where ReSharper really shines (and CodeRush and their ilk). Updating the constructor and adding a backing field for the IWidgetPublisher can be done with just a couple key strokes. With the cursor in the mockWidgetPublisher.Object text, Alt+Enter brings up this ReSharper “quick fix” menu:

That default choice is what we want, so just press Enter to add it to the constructor’s signature, as you see below. Moving the cursor onto that new parameter in the constructor and again using Alt+Enter, ReSharper brings up the “quick fix” choices below and again, the first choice is the appropriate one, so Enter finishes up the code to match what you saw just above.

CODE: Here are the changes ReSharper implemented.

 public class WidgetActivator

{

     private readonly IWidgetLoader _widgetLoader;

     private readonly IWidgetPublisher _widgetPublisher;

     public WidgetActivator(IWidgetLoader widgetLoader, IWidgetPublisher widgetPublisher)

     {

         _widgetLoader = widgetLoader;

         _widgetPublisher = widgetPublisher;

     }

     public WidgetActivator(IWidgetLoader widgetLoader)

     {

         _widgetLoader = widgetLoader;

     }

     public void Execute()

     {

         _widgetLoader.Load();

     }

}

TEST: Analogous to exercising the WidgetLoader, now we want the IWidgetPublisher to do some work.

[Test]

public void Execute_delegates_to_IWidgetPublisher_to_publish_widget()

{

    var mockWidgetPublisher = new Mock<IWidgetPublisher>();

    var stubWidgetLoader = Mock.Of<IWidgetLoader>();

    var activator = new WidgetActivator(stubWidgetLoader, mockWidgetPublisher.Object);

 

activator.Execute();

 

    mockWidgetPublisher.Verify(x => x.Publish(), Times.Once());

}

CODE: To get a clean compile we add Publish to the IWidgetPublisher interface.

public interface IWidgetPublisher

{

    void Publish();

}

CODE: Now the Verify assertion fails—because we have not yet wired up the Publish method call. Add the call to Publish to make it pass.

public class WidgetActivator

{

     private readonly IWidgetLoader _widgetLoader;

     private readonly IWidgetPublisher _widgetPublisher;

     public WidgetActivator(IWidgetLoader widgetLoader, IWidgetPublisher widgetPublisher)

     {

         _widgetLoader = widgetLoader;

         _widgetPublisher = widgetPublisher;

     }

     public WidgetActivator(IWidgetLoader widgetLoader)

     {

         _widgetLoader = widgetLoader;

     }

     public void Execute()

     {

         _widgetLoader.Load();

         _widgetPublisher.Publish();

     }

}

That final line of code made our test turn green! But wait a minute—the first test is failing now! How do I know? Because whenever I get the code to compile I run all tests, not just the latest test.

Test Runners

Visual Studio comes with a built-in test runner for unit tests, but it is only compatible with MSTest unit tests, not NUnit unit tests, as I prefer to use. Here is why:

#

Feature

MSTest

NUnit

1

Visual Studio support to run tests

Built-in

Requires NUnit Test Adapter

2

Visual Studio test templates

Built-in

None

3

Tests runnable outside VS

No

(NUnit GUI console)

4

Much faster startup time for each run

5

Fluent assertion interface

6

Rich attribute set

MSTest has a minor advantage in row 1, in that the test runner is built-in. But if you use ReSharper or NCrunch they provide built-in test runners as well—which are NUnit-compatible—so you would not even need the NUnit Test Adapter. MSTest also has a minor advantage in row 2, by having some project templates; however, test templates are not really a necessity as they are so simple to set up. The deal breakers to me, as indicated by the relative weightings in the table, are the fluent assertions and rich attribute set of NUnit. More details on those shortly.

Whichever unit test framework and ancillary tools you choose, you will have a test runner available in Visual Studio so it is a simple matter to re-run all tests as needed so you will be kept apprised of when your code changes have ripple effects into other tests.

The test under development passes, as I stated, but now the previous test fails on the Execute call. That test never supplied an IWidgetPublisher so attempting to call Publish on a null object throws an exception. This is apparently exposing a weakness in our set of behaviors thus far: in essence, the code is saying that we do not expect null objects passed in but we have not codified that into a test. In actuality, that was a system design choice on my part. When I do dependency injection I prefer to use an IoC container, as I mentioned in part 2. One advantage of using such a container to automate DI over using manual injection is that no IoC containers that I am aware allow nulls to be passed in as a constructor dependency.

TEST: So we just need to go back and give the prior test an IWidgetPublisher to avoid getting this exception. Notice how this test uses a mock and a stub exactly the opposite of the latest test.

 

[Test]

public void Execute_delegates_to_IWidgetLoader_to_load_widget_details()

{

    var mockWidgetLoader = new Mock<IWidgetLoader>();

    var stubWidgetPublisher = Mock.Of<IWidgetPublisher>();

    var activator = new WidgetActivator(mockWidgetLoader.Object, stubWidgetPublisher);

 

    activator.Execute();

 

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

}

 

[Test]

public void Execute_delegates_to_IWidgetPublisher_to_publish_widget()

{

    var mockWidgetPublisher = new Mock<IWidgetPublisher>();

    var stubWidgetLoader = Mock.Of<IWidgetLoader>();

    var activator = new WidgetActivator(stubWidgetLoader, mockWidgetPublisher.Object);

 

activator.Execute();

 

    mockWidgetPublisher.Verify(x => x. Publish(), Times.Once());

}

 Now both tests pass!

Here is the first time we introduce the refactor step of the Red-Green-Refactor process introduced in part 1. We have now outfitted 3 of the 4 unit tests for the two-argument constructor; only the very first test is still using the one-argument version. So to make it a bit tidier, let’s add a stub to that first test so it, too, can use the two-argument form, allowing us to delete the one-argument constructor.

TEST: Add a stub to pass to the two-argument constructor.

 [Test]

public void WidgetActivator_constructor_accepts_an_IWidgetLoader()

{

    var mockWidgetLoader = new Mock<IWidgetLoader>();

    var stubWidgetPublisher = Mock.Of<IWidgetPublisher>();

    var activator = new WidgetActivator(mockWidgetLoader.Object, stubWidgetPublisher);

}

CODE: Delete the one-argument constructor.

 

public class WidgetActivator

{

    private readonly IWidgetLoader _widgetLoader;

    private readonly IWidgetPublisher _widgetPublisher;

    public WidgetActivator(IWidgetLoader widgetLoader, IWidgetPublisher widgetPublisher)

    {

        _widgetLoader = widgetLoader;

        _widgetPublisher = widgetPublisher;

    }

    public WidgetActivator(IWidgetLoader widgetLoader)

    {

        _widgetLoader = widgetLoader;

    }

    public void Execute()

    {

        _widgetLoader.Load();

        _widgetPublisher.Publish();

    }

}

Run the tests again and they still pass, confirming that our refactor did not change the code’s behavior in any way. Whenever refactoring keep in mind the developer’s version of the Hippocratic Oath:

Cleanup your code—but do no harm!

Now that we have a loader and a publisher, the next most important behavior is that if there are no details for the loader to load, the Execute method should return false. In this test, I am using two stubs because neither of them is the focus of the test—here we are interested in what the Execute method is doing.

TEST: Create the basic test.

[Test]

public void Execute_returns_false_if_no_details_to_load()

{

    var stubWidgetLoader = Mock.Of<IWidgetLoader>();

    var stubWidgetPublisher = Mock.Of<IWidgetPublisher>();

    var activator = new WidgetActivator(stubWidgetLoader, stubWidgetPublisher);

 

    var result = activator.Execute();

 

    Assert.That(result, Is.False);

}

Constraints and Fluent Assertions

The crux of this test is the assertion in the final line: the Assert.That() method call. This single method—albeit with a large number of overloads—is the method to use for most validation in NUnit tests. It has the general form:

Assert.That( actual, constraint )

The first argument is your actual result. The second argument is a Constraint object that specifies what about the result you are validating. This constraint-based model, introduced fairly recently with NUnit 2.4, is what provides the fluent API of NUnit. Here are a few other sample assertions possible with Assert.That (see the NUnit documentation for many more):

Numerical

* Assert.That(2 + 2, Is.EqualTo(4) );

* Assert.That(2 + 2, Is.Not.EqualTo(5) );

* Assert.That( 5.5, Is.EqualTo( 5 ).Within(0.5) );

* Assert.That( 5.5, Is.EqualTo( 5 ).Within(15).Percent );

* Assert.That( 42, Is.InRange(1, 100) );

* Assert.That( 3, Is.LessThan( 5 ) | Is.GreaterThan( 10 ) );

String

* Assert.That( "Hello!", Is.Not.EqualTo("HELLO!") );

* Assert.That( "Hello!", Is.EqualTo("HELLO!").IgnoreCase );

* Assert.That( phrase, Is.StringContaining( "fail" ) );

* Assert.That( phrase, Is.StringMatching("abc.*test" ) );

Earlier in this article I mentioned that NUnit’s fluent assertion interface weighed heavily in selecting NUnit as my choice of test framework. NUnit’s constraint-based model above provides this fluent interface (first introduced in 2005 by Martin Fowler). The key element to observe is the combination of method chaining (tying output of one method into the input of the next) and the readability that ensues due to the flow of text. As an example, above you see one Assert call that uses this constraint:  Is.EqualTo( 5).Within(15).Percent. That chains together 4 elements nicely so that the entire statement, in English, reads “Assert that 5.5 is equal to 5 within 15 percent.”

A fluent interface lets you just read your tests. Why is this useful? Consider these two assertions, one using MSTest and one using NUnit. Contrast their readability—literally, read them out loud—and you will see why a fluent interface is advantageous:

MSTest

Assert.IsNotNull(Players.Where(x => x.Name.Equals("Cross");

NUnit

Assert.That(Players, Has.Some.With.Property("Name").EqualTo("Cross");

If you can read your tests when you write them, so can other members of your team. (And so can you two weeks from now :-). They are that much easier to comprehend. One more example—this is how to check for an expected exception with MSTest:

[TestMethod]

[ExpectedException(typeof(ApplicationException))]

public void OutOfBoundsMoveThrowsExceptionTest()

{

    TicTacToeBoard b = new TicTacToeBoard();

    b.MakeMove(4, 3, null);

}

And this is how to do the same thing with NUnit (actually this does even more; it also checks the message of the exception):

[Test]

public void OutOfBoundsMoveThrowsExceptionTest()

{

    TicTacToeBoard b = new TicTacToeBoard();

    Assert.That(() => b.MakeMove(4, 3, null),

        Throws.Exception.TypeOf<ApplicationException>()

        .With.Message.Contains("Out of bounds"));

}

CODE: Make it pass by adding a return value to Execute. Notice there is no attempt to make it behave “correctly” from the perspective of the system—we only care about making it behave correctly for this test.

 public class WidgetActivator

{

    private readonly IWidgetLoader _widgetLoader;

    private readonly IWidgetPublisher _widgetPublisher;

    public WidgetActivator(IWidgetLoader widgetLoader, IWidgetPublisher widgetPublisher)

    {

        _widgetLoader = widgetLoader;

        _widgetPublisher = widgetPublisher;

    }

    public bool Execute()

    {

        _widgetLoader.Load();

        _widgetPublisher.Publish();

        return false;

    }

}

If this is your first exposure to TDD, returning a hard-coded value may seem odd (or, let’s face it, just plain wrong!). That is obviously wrong in the sense that the Execute method clearly needs to return a semantically-valid result, not just “false”. In the long run, that is true—and Execute will evolve to return something better. But the rules of TDD (enumerated in part 1) require that you write the least amount of code to make the current test pass. In this instance, returning false is it; the test now passes! If you can contain your skepticism over the value and usefulness of just returning false, you will see how this approach bears fruit as the journey continues next time, in part 4!

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 10 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.
 

Top Rated

The Zen of Code Reviews: Best Practices
 If you don't feel that you are getting helpful and comprehensive feedback from code reviews, it may... Read more...

Improving Web Page Performance
 Visitors to a website are put off by having to wait for pages to load. Additionally, Google uses the... Read more...

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...

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...

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.