Ruby Style Mocking in .NET
I had a great discussion with a college about the difficulties of understanding the technical parts of the automated Mocking frameworks.
The one point that takes some time to grasp is the fact that methods are written within the test that are not actually called, but are stubs/mocks that will be called at a later time. This is true to all frameworks. He then suggested that having the ability to swap one type with another would help in understanding the flow of the test. So I whipped together some code to do just that.
Using this code it is possible to swap one type with another. The two types must have the same methods, but the swapping type doesn’t need to have all the methods of the original type.
Here is an example:
public class OriginalClass { public int ReturnOne() { return 1; } public static int StaticReturnOne() { return 1; } }
Static Method Swapping
Suppose we want to fake the static methods of the OriginalClass, we simply write a new class.
public class FakeClass { public static int StaticReturnOne() { return 2; } }
Note: apart from the names of the methods the two classes are not related.
Here is how we fake the calls,
- We Swap the OriginalClass with the FakeClass by: Swap.StaticCalls()
- All static calls to OriginalClass methods that exist in the FakeClass are diverted to the FakeClass.
- We Unswap the types at the end of the test by Swap.Rollback()
[TestMethod] public void SwapStatic_CallsFake() { Swap.StaticCalls<OriginalClass, FakeClass>(); Assert.AreEqual(2, OriginalClass.StaticReturnOne()); Swap.Rollback(); }
Instance Swapping
We can do the same with instances, we can create a new FakeClass and swap the instances.
public class FakeClass { public int ReturnOne() { return 2; } }
Note: again, apart from the names of the methods the two classes are not related, but they both might implement the same interface or base class and thus support refactoring.
Here is how we fake the calls,
- We Swap the next new OriginalClass with the FakeClass by Swap.NextNew().
- All calls to that OriginalClass method which exist in the FakeClass are diverted to the FakeClass.
[TestMethod] public void SwapInstance_CallsFake() { Swap.NextNew<OriginalClass, FakeClass>(); OriginalClass swappedInstance = new OriginalClass(); Assert.AreEqual(2, swappedInstance.ReturnOne()); }
Missing Methods
At this stage the missing methods of the swapped type can have 2 behaviors:
- Call the original class (Default or UndefinedMethods.CallOriginal)
- Do nothing and Return a default value (UndefinedMethods.Ignore)
This is set in the swap statements.
Downloads
Why Typemock-Isolator for TDD?
There is a long discussion in the ALT.NET group about TDD and Typemock, it is very interesting and I suggest that you read the thread.
Benefits of TDD
Although the benefits of using TDD are inconclusive, here are some benefits attributed to using TDD:
- Developers write more tests
- Tests use the API, so developers can get early feedback on the API design
- Developers have more Focus as the tasks are divided into small chunks
Why do we need to Mock?
In order to use TDD effectively the tests must
-
Run fast.
-
Run in isolation.
-
Self Contained.
-
Race Safe.
-
Independent.
In order to make sure that we have fast tests, that the tests are self contained and don’t rely on external resources, we need to test our code in isolation from the rest of the system. This is done by mocking out components that are not part of our test, and testing only the unit logic.

TDD and Typemock-Isolator
So where does Typemock-Isolator fit in and how does it compare to other frameworks?
When using TDD with legacy code or 3rd party libraries, the benefits of Typemock-Isolator are well known, so I will not talk about those area’s but about green-field projects.
Developing with Typemock-Isolator, developers will be able to do all the stuff the other frameworks and manual mocks/stubs allow with the addition of being able to mock static methods, private methods and types and a chain of calls (fluent interfaces) in one go (As well as better integration with Visual Studio).
These features make it simpler to divide the code into small chunks – leading to more focus and more tests.
The API’s are still reviewed as tests are written using the API so early feedback of the API’s are part of this process. This is achieved with the freedom to use any internal design of the unit: Extension Methods, Linq, Fluent interfaces, Singletons and Factories.
Other frameworks will force the developer to use DI as an internal pattern. This might be good, but might not be good. It might leave public API’s that where not meant to be public. It will leave the ability to inject an alternative implementation that might ruin the system. It will probably lead to developing extra functionality to support validating and error handling of the injected components. This might be a YAGNI smell that will require extra development and tougher maintenance. Is DI a silver bullet design pattern? Or do you want the Freedom to refactor the code to best suit the product – I know that I do, this is what Typemock-Isolator will give: The benefits of TDD with the freedom to refactor your code to any design.
Decorator feature enhancement
[Cross Posted in TypeMock Insider Blog]
Typemock-Isolator has a little know Decorator feature that allows developers to simply add capabilities to their test framework (all test framework).
Using this feature Typemock-Isolator creates the [VerifyMocks] decorator that automatically verifies the mocks at the end of your tests.
To create a custom decorator simply extend the DecoratorAttribute and implement the Execute method.
public override object Execute()
{
// Trace start of method
Console.WriteLine(“Entering Method:”+
OriginalMethod.ToString());
// Execute the original method
return base.CallDecoratedMethod();
}
To support multiple decorators on the same test method, Typemock-Isolator makes sure that even if a developer forgot to call CallDecoratedMethod() the test method will still run. This is done by calling the decorated method if it wasn’t explicitly called.
We discovered that some Decorator implementers want more control and need to explicitly make sure that the test method was NOT called.
A new API was added in version 4.2 to do just that.
Once this is called (inside Execute), the decorator mechanism will not call the test method.
Of course if there is another decorator on the test method that calls CallDecoratedMethod() the test method will be executed.
Tips and Tricks
I am happy to announce that we have opened a Typemock Blog
The blog will host posts from Typemock developers and will give inside information and tip and tricks.
Lior Friedman has already posted a explanation of the difference between Mock and MockObject
Dependency Injection with TypeMock
The has been some buzz about Dependency Injection lately (here is another thread). But I want to actually show how TDD with TypeMock can lead to a DI solution, and how the tests will step by step naturally lead to the DI solution when the business features require it.
Lets start with a very simple example that displays an error message in a Windows Message Box. This is a requirement from the customer, just to make things simple we have a ValidateThatNameIsOk() method that displays a Message when the Name is empty.
Part 1 – Initial Code
Listing 1 – the test.
[Test]
public void ValidateThatNameIsOk_Passes_WhenNameExists()
{
SomeApplication classUnderTest = new SomeApplication();
classUnderTest.ValidateThatNameIsOk(“r”);
}
Listing 2 – the simplest solution
public void ValidateThatNameIsOk(string name)
{
}
Now lets add a failing case (we must mock out the MessageBox or we will halt the test)
Listing 3 – another test.
[Test,VerifyMocks]
public void ValidateThatNameIsOk_Fails_WhenNameIsEmpty()
{
// Record Mocks
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
MessageBox.Show(“A Name must be entered“);
recorder.Return(DialogResult.OK);
}
SomeApplication classUnderTest = new SomeApplication();
classUnderTest.ValidateThatNameIsOk(“”);
}
Listing 4 – and here is the simplest solution.
public void ValidateThatNameIsOk(string name)
{
if (name.Length==0)
{
MessageBox.Show(“A Name must be entered”);
}
}
Part 2 – More Features Request
Our application is a success and we managed to deliver on time (because we didn’t write unneeded code). After some time our customer asked for a new feature: “run the application in batch mode”. Now we cannot use MessageBox.Show() any more. Now we need to write the message to the console (or a file).
Lets start with the test*.
Listing 5
[Test,VerifyMocks]
public void ValidateThatNameIsOk_FailsAndWritesToConsole_WhenNameIsEmpty()
{
// Record Mocks
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
Console.WriteLine(“A Name must be entered”);
recorder.CheckArguments();
}
SomeApplication classUnderTest = new SomeApplication();
classUnderTest.ValidateThatNameIsOk(“”);
}
Part 3 – First Solution, inline-condition
private bool useConsole = false;
public bool UseConsole
{
set { useConsole = value; }
}
public void ValidateThatNameIsOk(string name)
{
if (name.Length==0)
{
if (useConsole)
Console.WriteLine(“A Name must be entered”);
else
MessageBox.Show(“A Name must be entered”);
}
}
Part 4 – Extract the Message Class
public class Message
{
private static bool useConsole = false;
public static bool UseConsole
{
set { useConsole = value; }
}
public static void Show(string message)
{
if (useConsole)
Console.WriteLine(“A Name must be entered”);
else
MessageBox.Show(“A Name must be entered”);
}
}
and here is the validation method.
public void ValidateThatNameIsOk(string name)
{
if (name.Length==0)
{
Message.Show(“A Name must be entered”);
}
}
Our Console test (and the batch runner) will need to call Message.UseConsole = true and all our tests will pass.
Now we need to add a feature to write the message to an external file.
Part 5 – Add another output stream and Polymorphism
To add another output stream (a log file for example), we would write a test which will lead to a change in the Message class, the simplest way is to change the boolean to an enumerator and change the if statement to a switch,
private static MessengerType messenger = MessengerType.MessageBox;
public static MessengerType Messenger
{
set { messenger = value; }
}
public static void Show(string message)
{
switch (messenger)
{
case MessengerType.MessageBox:
MessageBox.Show(message);
break;
case MessengerType.Console:
Console.WriteLine(message);
break;
case MessengerType.File:
File.AppendText(message);
break;
}
}
which will lead to a refactor to use polymorphism.
Listing 8 – Using Polymorphism
public interface IMessage
{
void Show(string message);
}
public class MessageBoxMessage : IMessage
{
public void Show(string message)
{
MessageBox.Show(message);
}
}
public class ConsoleMessage : IMessage
{
public void Show(string message)
{
Console.WriteLine(message);
}
}
And the Message class
public class Message
{
private static IMessage messenger = new MessageBoxMessage();
public static IMessage Messenger
{
set { messenger = value; }
}
public static void Show(string message)
{
messenger.Show(“A Name must be entered”);
}
}
Take a look at the code. We have reached the Dependency Injection pattern. Here is how we inject the correct messenger.
Message.Messenger = new ConsoleMessage();
At this point all our tests still pass without any change
Conclusion
We have seen that using TDD and TypeMock, it is possible to build software that can handle change in an incremental manner. When a business need requires the Dependency Injection Pattern, refactor-ing the code will lead to the correct solution, without needing to design it up front. The tests won’t need to be rewritten and we follow the YAGNI principle.
*How do I manage to mock Console.WriteLine in mscorlib?
Great Time in Tech Ed Barcelona
We had a great time in Barcelona, The TechEd team has done it again and have created a top-notch conference. Apart from not being able to get tickets to the Barcelona Football match, we practically had everything made out for us.
We had some really good talks and met up with great people from the industry. Thank you all.
TypeMock is a Silver Bullet
During the TechEd in Bacelona, I overheard developers talking about TDD and Mocking. Then I heard one of them say that TypeMock is a Silver Bullet, it can just help you solve all your mocking problems. I love that, thanks guys.
Roys Test Name Convention
I just loved the way Roy explained how developers normally name their tests without really thinking about them. for example SumNegitiveNumber5 (yup, I have been down that road before) and his naming convention really make sense.
But what I really liked was the template he wrote and how the Tab key browses through the three the different parts of the name.
Rollback for database testing
Roy Osherove had a good speak in TechEd Barcelona 2007, about using the roll back attribute for database testing, and it works really well, keeping the test case isolated. Except in cases where the production code ignores transactions that are higher up in the hierarchy. This will happen if the TransactionOption is RequiresNew
Roy suggested to always use: Supported, but we believe that there should be a way to test you code even if you require and need to use another transactions.
So here is how I would do it with TypeMock.
I would create a new attribute for the rollback and make sure that all future TransactionOptions are Mocked.
This way our test will look like:
[TestMethod,Rollback,VerifyMocks]
public void MyDatabaseTest()
{
}
Here is the code, to enable this (for any test framework) simple add the attribute.
[AttributeUsage(AttributeTargets.Method)]
public sealed class RollBackAttribute : DecoratorAttribute
{
public override object Execute()
{
// Start transaction
ServiceConfig config = new ServiceConfig();
config.Transaction = TransactionOption.RequiresNew;
ServiceDomain.Enter(config);
// make sure that all future Transactions rely on this transaction by mocking all sets to the Transaction
Mock serviceConfigMock = MockManager.MockAll<ServiceConfig>(Constructor.NotMocked);
serviceConfigMock.ExpectSetAlways("Transaction");
try
{
// run our tests
return base.CallDecoratedMethod();
} finally
{
// clear unused mocks
serviceConfigMock.Clear();
// rollback database
if(ContextUtil.IsInTransaction)
{
ContextUtil.SetAbort();
}
ServiceDomain.Leave();
}
}
}
DotNetRocks Interview
I had a real fun talk with Richard and Carl on DotNetRocks. You can listen to the show here.
The highlight was a grand piano being delivered to Carl during the interview.
Although the show was mainly targeted at Dependency Injections, there are many other design issues that are not required because TypeMock is design agnostic. One is the unnecessary need for virtual method Take a look at Jeremy’s post for more details.
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
