The McDev Blog

Kevin McKelvin's perspective of the Ruby world.

Getting Started With TypeMock Isolator (in VS2010)

I started playing with TypeMock Isolator this morning as an alternative to using the Moles framework from Microsoft Research.

Isolation frameworks allow you to intercept and redirect calls made to concrete call sites and replace them with a delegate. If that sounds like a bit of gibberish consider this scenario:

If you have a class that makes a call to DateTime.Now to check against an expiry date and you want to test that it expires on a future date, you need to control what the static DateTime.Now returns. That’s where an isolator comes in.

To get started with TypeMock, once you have it downloaded and installed you just need to add references to the DLLs from your GAC. TypeMock’s website still shows VS2008 instructions which are slightly different from VS2010.

To get going with NUnit and TypeMock, first create a class library:

image

Add a reference to NUnit from NuGet

image

When working with C#, add references to TypeMock and Typemock.ArrangeActAssert to your unit test project.

image

And you’re ready to start writing isolated tests!

To run a test with TypeMock Isolator is pretty simple, just add an Isolated attribute to your unit test and use TypeMock’s fluent Isolate API to mock the method calls.

Returning to our DateTime example, here’s how you could Isolate a static call to DateTime.Now:

1
2
3
4
5
6
7
[Test, Isolated]
public void ReplaceDateTimeNowWithValue()
{
    Isolate.WhenCalled(() => DateTime.Now).WillReturn(new DateTime(2010, 1, 2));

    Assert.AreEqual(new DateTime(2010, 1, 2), DateTime.Now);
}

Mocking out a concrete instance method is also easy. Below, I’m mocking the behaviour of a method in a sealed class - UserRepository.GetQuery()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[Test, Isolated]
public void LoginWithRealRepository()
{
    // arrange
    var ur = Isolate.Fake.Instance<UserRepository>();
    Isolate.WhenCalled(() => ur.GetQuery()).WillReturn(new List<User>
                                                    {
                                                        new User
                                                            {
                                                                Username = "kevin",
                                                                Password = "abc"
                                                            }
                                                    }.AsQueryable());

    //act
    var login = new UserLoginController(ur);
    User loggedInUser = login.Login("kevin", "abc");

    // assert
    Assert.IsNotNull(loggedInUser);
}

There’s a great debate about when isolation frameworks should and shouldn’t be used. Having learnt how to do unit testing via TDD without requiring an isolator I would still use it sparingly, only pulling it in when I want to test the class whose responsibility is to bridge the divide between my code and a global state such as a database or the file system. A tool like this isn’t an excuse to write code with mixed concerns simply because it can be isolated later. Writing testable code helps drive good object oriented design and loose coupling – both are important design objectives.

TypeMock Isolator is an impressive bit of software. There are clear advantages in using this in the future.

It allows developers to be more pragmatic about when to write polymorphic code and focus more on testing behaviour rather than how to fake things in tests. Truth be told it makes unit testing C# feel a lot more like testing in dynamic languages.

Links:

TypeMock Home Page

TypeMock Isolator

@Typemock on Twitter