Mocking with TypeMock

TypeMockI've been a slow convert to the whole test-driven development movement. I'm ashamed, but it's true. I've believed in TDD in principle, but when it came down to it, designing specifically for testability always made my code feel so bloated. I always ended up writing unit tests after the fact, and many times would end up writing loads of helper objects and dummy interface implementations to get things to work.

No longer.

We started looking at mock object frameworks for the latest project at work. After checking out Rhino Mocks (admittedly a decent framework), we stumbled upon TypeMock.

Holy crap, this thing is hot. In technical terms, you might call it the bomb-diggity.

There are several things that make TypeMock the framework to go with. The syntax of the "Natural Mocks" is nice and clean, making the majority of the mocking easy to use. It'll mock static methods, constructors (and static constructors), and non-public methods - stuff Rhino [currently] won't let you do.

"But," you might say, "mocking frameworks are hard to work with because you can't really see what's going on 'behind the scenes.'"

No longer! TypeMock has a trace utility where you can watch in real-time as the mock framework sets up and fulfills expectations. If you want to know what it's doing, check the window. Want to know specifically what expectations are set up and which ones were left? It's right there. No more fighting with stack traces and expectation exceptions. It really doesn't get any easier than this.

A co-worker showed me some code he had written using Rhino. Frankly, I found it confusing and it wasn't his code making it that way. I tried writing my own tests in it and had a heck of a time figuring it out. I picked up TypeMock this morning and minutes later was flying through it.

Ever tried to test an abstract class? You know how you have to create a dummy class that implements all the abstract stuff just so you can test the functionality? Not anymore - you can get a mock of the abstract class with no "placeholder" or "dummy" classes. Ever tried to test a factory that returns values based on configuration files in the filesystem? You know how you end up having to dump fake config to just the right spots in the filesystem in order to test that factory? And you know how much more trouble it is to test classes that make use of that factory? Forget that. No more having to fight with all that. It's a piece of freakin' cake.

Let's use that factory example. Say I have a factory called CoolFactory that has a method CoolFactory.GetCoolObject(). That method looks up a value in configuration and returns an object of type CoolObject. Now say you have a class called WorkingClass (pun?) that uses the CoolFactory to do some work in the WorkingClass.DoWork() method.

You used to have two options: either over-architect CoolFactory and have a load of various pluggable providers that the factory could use and clutter the API with so you can sub in configuration at test time; or set up configuration, dummy objects, etc., all to support a single test.

With TypeMock, you can mock that static CoolFactory.GetCoolObject() method and skip all that. Here's what an NUnit test might look like:

[Test]
public void MyTest(){
  // Set up the object you want the factory to return here
  CoolObject factoryGenerated = new CoolObject();

  // Record the actions you want to play back
  // and tell the factory to return your object.
  using (RecordExpectations recorder = new RecordExpectations()){
    CoolFactory.GetCoolObject();
    recorder.Return(factoryGenerated);
  }

  // Call the method that uses the factory
  WorkingClass testObj = new WorkingClass();
  testObj.DoWork();

  // Make your test assertions here...

  // Verify the DoWork method called the factory
  MockManager.Verify();
}

That's it - when the DoWork method calls the factory, it'll return the object you set up. No need to dump config to the filesystem, over-architect the factory, or dummy up a lot of extra "helper" classes.

I haven't been this stoked about a technology for quite some time.

Now, I'm using the Enterprise edition (they offer a "community edition" that doesn't have the "Natural Mocks" in it - don't bother with that, you want the Natural Mocks). I'm not sure if I'd have been so excited if I was stuck at the "community edition" level. But I'm not, so I'll play ignorant and revel in what I've got.

No more designing for testability! No more huge efforts to create dummy objects to get various components working and tested!

You know what? With a framework like TypeMock, I can 100% buy into test-driven development. I can keep API as a deliverable and still get full test coverage - I get my cake and I eat it, too.

Check out TypeMock. You'll be glad you did.

posted on Thursday, September 28, 2006 5:43 PM | Filed Under [ GeekSpeak ]

Comments

Gravatar # Eli Lopian’s Blog (TypeMock) » Blog Archive » Low Coupling is NOT a Silver Bullet
by www.elilopian.com at 10/4/2006 12:55 PM
Gravatar # Eli Lopian’s Blog (TypeMock) » Blog Archive » Creating a Trade Show Booth
by www.elilopian.com at 2/27/2007 2:12 PM
Gravatar # re: Mocking with TypeMock
by Brian Rasmussen at 1/30/2008 4:19 AM
Why would your CoolObject have a public default constructor? Isn't the point of having the CoolFactory to centralize object creation?

Anyway, for the sake of argument let's just say that you have a public constructor.

Your goal is to test WorkingClass and as such your test shouldn't depend on CoolObject as well since this is an implementation detail to WorkingClass as far as I can tell from your example. I.e. to get rid of the dependency, you need to mock CoolObject as well.

Is there any way to supply a mocked object to the recording part of your example?
Gravatar # re: Mocking with TypeMock
by Brian Rasmussen at 1/30/2008 5:14 AM
Your example made me look at natural mocks again (we have the Enterprise edition as well, but we're using Reflective mocks - mainly because that was the only available option when we started using TypeMock).

Anyway, you can cut the dependency to CoolObject in your example by including the following in your using-block:

CoolObject factoryGenerated = RecorderManager.CreateMockedObject(typeof(CoolObject), Constructor.Mocked) as CoolObject;

Then you can deleted the creation of CoolObject and thus be free of this dependency.

One not so cool thing about Natural mocks in my experience is that they are somewhat harder to debug. Everything just acts really weird when you try to e.g. single step through recording code. With Reflective mocks you can easily monitor TypeMock's view of the situation with the Tracer tool.
Gravatar # re: Mocking with TypeMock
by Harish at 7/22/2008 10:20 PM
Travis,

This is news to me that, we are using typemock for next generations.

I would like to see how this is working... :)

will stop by..

Good findings
Harish
Gravatar # re: Mocking with TypeMock
by Nijish at 9/24/2008 8:22 AM
Hi Travis,

I am struggling to find out a method to mock the constructor of a class. Please help me.

I have one method which instantiate an private object within it. Please see the code below.

MyClass{
ReturnType MyMethod(){
Context context = new Context(Value1, Value2)
ReturnType ReturnValue = GetReturnValue(context);
Return ReturnValue;
}
}

Here Value1 and Value2 are Private Members of MyClass.

Please let me know how do I create a mock object of context and have my own value in it?..


With Regards
Nijish NT
Gravatar # re: Mocking with TypeMock
by Travis Illig at 9/24/2008 8:25 AM
This is totally possible to do, but rather than set the precedent of answering all questions in my comments (not something I can support), I'd recommend posting your question to the Typemock Forums: http://www.typemock.com/community/index.php

Doing that will not only get your question answered faster and in a more easily accessible way, it enables other members of the community to benefit from the answer in a central location.
Comments have been closed on this topic.