01 August 2014

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

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

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.

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

2019-img2C.gifTest 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.

2019-img32.gif

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.

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.

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:

2019-img2D.jpg

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.

2019-img2E.jpg

CODE: Here are the changes ReSharper implemented.

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

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

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.

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.

2019-img2C.gifTest 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

2019-imgE.gifBuilt-in

Requires NUnit Test Adapter

2

Visual Studio test templates

2019-img11.gifBuilt-in

None

3

Tests runnable outside VS

No

2019-imgE.gif(NUnit GUI console)

4

Much faster startup time for each run

 

2019-imgE.gif

5

Fluent assertion interface

 

2019-imgE.gif2019-imgE.gif2019-imgE.gif2019-imgE.gif

6

Rich attribute set

 

2019-imgE.gif2019-imgE.gif2019-imgE.gif2019-imgE.gif

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.

2019-img32.gif

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.

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.

CODE: Delete the one-argument constructor.

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.

2019-img2C.gifConstraints 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:

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):

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:

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

2019-img32.gif

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.

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!

Keep up to date with Simple-Talk

For more articles like this delivered fortnightly, sign up to the Simple-Talk newsletter

Downloads

This post has been viewed 12089 times – thanks for reading.

  • Rate
    [Total: 11    Average: 4.9/5]
  • Share

Michael Sorens

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 +

View all articles by Michael Sorens

Related articles

Also in .NET

Posting Form Content via JavaScript

Web-based applications run smoother if instead of using the traditional form method, they use JavaScript to post data to the server and to update the user interface after posting data: It also makes it easier to keep POST and GET actions separated. SignalR makes it even slicker; it can even update multiple pages at the same time. Is it time to use JavaScript to post data rather than posting via the browser the traditional way?… Read more

Also in .NET Framework

What's New in C# 6

The C# language itself has changed little in version 6, the main importance of the release being the introduction of the Roslyn .NET Compiler Platform. However the New features and improvements that have been made to C# are welcome because they are aimed at aiding productivity. Paulo Morgado explains what they are, and how to use them.… Read more

Also in refactoring

SQL Server System Views: The Basics

When maintaining or refactoring an unfamiliar database, you'll need a fast way to uncover all sorts of facts about the database, its tables, columns keys and indexes. SQL Server's plethora of system catalog views, INFORMATION_SCHEMA views, and dynamic management views contain all the metadata you need, but it isn't always obvious which views are best to use for which sort of information. Many of us could do with a simple explanation, and who better to provide one than Rob Sheldon?… Read more

Also in .NET Framework

The Zen of Code Reviews: Review As If You Own the Code

A code review is a serious business; an essential part of development. Whoever signs off on a code review agrees, essentially, that they would be able to support it in the future, should the original author of the code be unavailable to do it. Review code with the energy you'd use if you owned the code. Michael Sorens runs through the principles of reviewing C# code.… Read more

Join Simple Talk

Join over 200,000 Microsoft professionals, and get full, free access to technical articles, our twice-monthly Simple Talk newsletter, and free SQL tools.

Sign up