Geeks With Blogs

News

This blog has moved to ericnelson.wordpress.com

 Subscribe in a reader

Add to Google Reader or Homepage


Links
View my teams slideshare
These postings are provided "AS IS" with no warranties, and confer no rights.



IUpdateable has moved to ericnelson.wordpress.com Please visit http://ericnelson.wordpress.com

This is the second guest post from Gil Zilberfeld who works at TypeMock and kindly agreed to do a couple of guest posts on Mocking . The first was an Introduction to Mocking.

Typemock Isolator – Much more than an Isolation framework

image

In my last post, I showed how to fake a dependency. But this involved doing a couple of things. First, it involved changing the original method. Then, I had to write wrappers (a real wrapper and the fake wrapper) and finally, I had to inject the fake object in the test. This is a lot of work, even for a very simplistic example. The solution for that is an isolation framework.

Isolation frameworks isolate the code from their dependencies, but they do it programmatically, and without hassle. What makes Typemock Isolator 2010 different than other frameworks (like Rhino Mocks and Moq) is that you don’t need to change the tested code just to test it.

Let’s look at the test we got last time – using a fake Message Queue to test that the message was called:

[TestMethod]
public void Send_StringMessage_MessageWasSent()
{
    var fakeQueue = new FakeMessageQueue();

    var server = new Server();
    server.SendMessage(fakeQueue, "message");

    Assert.IsTrue(fakeQueue.messageWasSent); 
}

We’re actually doing two things in this test with our fakeMessageQueue object. The first is changing behavior – the SendMessage method does not call the original SendMessage method. The second is testing that the method was called. We do this by using a public field in the fake object.

We can accomplish the same things much easily with Typemock Isolator. Let’s go back to the original method, before we changed it:

public class Server
{
    public void SendMessage(MessageQueue queue, object message)
    {
        queue.Send(message);
    }
}

With Isolator, the test would look like this:

[TestMethod]
public void Send_StringMessage_VerifyMessageWasSent()
{ 
    MessageQueue fakeQueue = Isolate.Fake.Instance<MessageQueue>();
    
    var server = new Server();
    server.SendMessage(fakeQueue, "message");

    Isolate.Verify.WasCalledWithAnyArguments(() =>fakeQueue.Send(null));
}

As you can see, there are a couple of changes. The first is the Isolate.Fake.Instance statement. It creates a fake MessageQueue object. This is the original MessageQueue type; only method calls on it are ignored when they are called. So when the server calls the Send method on the fakeQueue it is ignored.

The other half of the equation is to verify that the method was called. Instead of planting a field to save the result, we use the Isolate.Verify API to test that the method was called. We don’t care about arguments sent to the method, so we put null in the argument, just to keep the compiler happy.

This is the basic stuff. What really separates Isolator from the rest is that Isolator can change and verify method calls on any method: Static and sealed classes (like the “untestable” SharePoint).

And it can change objects in mid-run. Let’s say my method under test looks like this:

public void SendMessage(object message)
{
    MessageQueue queue = new MessageQueue(@".\myQueue");
    queue.Send(message);
}

This time the MessageQueue is created inside the method under test! But Isolator can help here as well:

[TestMethod]
public void Send_StringMessage_VerifyMessageWasSent()
{
    MessageQueue fakeQueue = Isolate.Fake.Instance<MessageQueue>();
    Isolate.Swap.NextInstance<MessageQueue>().With(fakeQueue);

    var server = new Server();
    server.SendMessage("message");

    Isolate.Verify.WasCalledWithAnyArguments(() =>fakeQueue.Send(null));
}

Notice the Swap.NextInstance call? It replaces the next time a MessageQueue is created. And that exactly happens inside the method under test.

Typemock Isolator has lots of other capabilities that make it easier to write tests– like recursive fakes (the ability to create a full object tree of fakes in a single line) and Intellitest, auto completion for testing statements.

But don’t take my word for it. Take Isolator for a ride – it’s about easy unit testing.

Gil Zilberfeld

Technology Evangelist | TypemockBlog | Twitter

Posted on Monday, February 22, 2010 1:51 PM Alt.NET , Project NEric , GuestPost | Back to top


Comments on this post: GuesPost: Typemock Isolator – Much more than an Isolation framework

# re: GuesPost: Typemock Isolator – Much more than an Isolation framework
Requesting Gravatar...
Gil,
I'd like to ask a question, and hope it's not going to sound as an attack.

The method SendMessage is creating a MessageQueue using new operator.
You could abstract MessageQueue away and work againt a contract, a healthy thing to do anyways.
A factory would produce a MessageQueue, replacing the untestable new operator. Factory itself
would get injected as a dependency into whatever the class you are testing (Server?).
This way the system under test code would look the next:

public void SendMessage(object message)
{
IMessageQueue queue = messageQueueFactory.Create(@".\myQueue");
queue.Send(message);
}

I guess what I am trying to say is that with Isolator you get the job done, code is tested.
But the smells are not gone.
Thank you.
Left by Sean Feldman on Feb 24, 2010 2:09 AM

# re: GuesPost: Typemock Isolator – Much more than an Isolation framework
Requesting Gravatar...
Hi Sean,

Thanks for the comment - and I get this question a lot.

Yes, I can abstract the MessageQueue (if you read the first post, you'll see that I did that in the past). I can put that in the factory, as you suggested, or inject an IMessageQueue implementing object that wraps the MessageQueue in the constructor. And that would create decoupling in my code, which is considered a good thing.

(By the way, there are times when I can't do that. Did you know that refactoring code in regulated environments requires multiple signatures, sometimes 3 level up? Just for refactoring! Sometimes we don't have the luxury. But I digress).

However, this should come from my own understanding of the design and its consequences. Let's say I create the MessageQueue only once in the application. (We can talk about future use, but that's YAGNI). Isn't the code more readable when I use "new", instead of creating a factory, extracting the interface, creating a wrapper object (which may all introduce bugs on the way)?

I'm not saying don't do that. If you're willing to sacrifice readability for decoupling, good for you - as long as you understand the implications.

After all is said and done, in any design you've selected, you'll need to test as well. And Isolator help you test in whichever design you choose.

Thanks for the question again.

Gil Zilberfeld
Typemock
Left by Gil Zilberfeld on Feb 24, 2010 8:30 AM

# re: GuesPost: Typemock Isolator – Much more than an Isolation framework
Requesting Gravatar...
Gil,

Thank you for detailed reply. I can definitely see where you coming from. Code design is a team decision, and each team decided how they want to do it. IMO to be able to support testing for both types of design is a very strong feature. With power comes responsibility, and I presume does a team have that responsibility, or not.

Thank you for the post.
Sean
Left by Sean Feldman on Feb 24, 2010 2:46 PM

Your comment:
 (will show your gravatar)


Copyright © Eric Nelson | Powered by: GeeksWithBlogs.net