Mocking frameworks are growing more and more in popularity these days, because to

some degree Unit Testing, via TDD or otherwise, has been growing in popularity.

This week at the Heartland Developer Conference I

gave a talk on what I call “practical” TDD. The talk goes over the basics of

TDD quickly, but is really targeted at those who have tried to do TDD but found it

difficult because they are not working on a team that has adopted the practice, or

they are not working a project that was built to be testable. I spent a good

bit of time working no what is the easiest path to help such people adopt TDD, because

adoption of such good practices is far more important to me than perfection in them.

As has been said many times, Good Enough is by definition, Good Enough.

After a good bit of research on the subject of mocking frameworks, I have come to

the simple conclusion that:

  1. This is an area that is growing still, as nearly every major framework differs on

    the coding approach. This is in stark contrast to testing frameworks which,

    to a one in .NET, all have settled on the NUnit 2.0 model of using attributes.

  2. That if you’re not using TypeMock then you’re just working to damned hard.

Now, I’m sure my friends (and there are many) who use Rhino Mocks will believe that

I must be over-stating the issue, but I tell you clearly I am not. TypeMock

is not built like any other mocking framework currently available, it uses the profiling

APIs and not polymorphism or encapsulation in order to intercept calls and provide

return values. Let me give you just a few examples of things which TypeMock

can do in a few short lines of code which Rhino Mocks simply cannot do at all.

Mocking Static Methods

Take the following code, and assume that we wish to mock MessageBox.Show which is

a static method:


          private

          void MyCoolMethod(string msg)

{ if (MessageBox.Show(msg) == DialogResult.OK) Console.WriteLine("OK"); else Console.WriteLine("Not

OK! Not OK!"); } 

.csharpcode, .csharpcode pre

{

font-size: small;

color: black;

font-family: consolas, “Courier New”, courier, monospace;

background-color: #ffffff;

/*white-space: pre;*/

}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt

{

background-color: #f4f4f4;

width: 100%;

margin: 0em;

}

.csharpcode .lnum { color: #606060; }

The following test will work perfectly to mock this call. No other hidden setup,

nothing more than a reference to TypeMock.dll and the following code:

        [Test]

        publicvoid MockMessageBoxShow()

{ MockManager.Init(); Mock mbMock = MockManager.Mock(typeof(MessageBox));

mbMock.ExpectAndReturn("Show", DialogResult.OK); MyCoolMethod("Here

we go again."); // Ensure that all expectations were met. MockManager.Verify();

}

.csharpcode, .csharpcode pre

{

font-size: small;

color: black;

font-family: consolas, “Courier New”, courier, monospace;

background-color: #ffffff;

/*white-space: pre;*/

}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt

{

background-color: #f4f4f4;

width: 100%;

margin: 0em;

}

.csharpcode .lnum { color: #606060; }

And with just that little code, just 4 lines dedicated to the mock, 2 of which should

be refactored to Setup and TearDown methods, we can mock a static method.

Not cool enough for you? Ok, fine.

Mocking Events

So you have something which expects an object to return certain events. This

example does require a professional license ofTypeMock, it will not work under

the Community Edition, but if you need this functionality then reallypay thenicefolks

their money.


          public

          class GUI

{ publicstring LovingCSharp {

get; set; } publicvoid Initialize()

{ this.LovingCSharp = string.Empty;

Button button = new Button(); button.Click += new EventHandler(button_Click);

} privatevoid button_Click(object sender,

EventArgs e) { this.LovingCSharp += "LOVE!";

} }

.csharpcode, .csharpcode pre

{

font-size: small;

color: black;

font-family: consolas, “Courier New”, courier, monospace;

background-color: #ffffff;

/*white-space: pre;*/

}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt

{

background-color: #f4f4f4;

width: 100%;

margin: 0em;

}

.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre

{

font-size: small;

color: black;

font-family: consolas, “Courier New”, courier, monospace;

background-color: #ffffff;

/*white-space: pre;*/

}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt

{

background-color: #f4f4f4;

width: 100%;

margin: 0em;

}

.csharpcode .lnum { color: #606060; }

Now let’s mock this up, call that event three times, and assert that our property

is set correctly.

        [Test]

        publicvoid MockFormWithEvents()

{ MockManager.Init(); // Mock button so that we can... Mock

btnMock = MockManager.MockAll(typeof(Button)); //

Handle all calls to add an event handler. MockedEvent evntMock = btnMock.ExpectAddEventAlways("Click");

GUI frm = new GUI(); frm.Initialize(); evntMock.Fire(this,

EventArgs.Empty); evntMock.Fire(this, EventArgs.Empty);

evntMock.Fire(this, EventArgs.Empty); Assert.AreEqual("LOVE!LOVE!LOVE!",

frm.LovingCSharp); // Ensure that all expectations were met. MockManager.Verify();

} } 

.csharpcode, .csharpcode pre

{

font-size: small;

color: black;

font-family: consolas, “Courier New”, courier, monospace;

background-color: #ffffff;

/*white-space: pre;*/

}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt

{

background-color: #f4f4f4;

width: 100%;

margin: 0em;

}

.csharpcode .lnum { color: #606060; }

Summary

These are just two examples, and don’t even delve into the whole “Natural Mocks” portion

of TypeMock. Do yourself a favor, download the evaluation, they’ll give you

30 days of all the features (which you can make any individual 30 days you’d like

BTW) and ask yourself why you’re jumping through all those hoops just to be

able to mock dependencies. With this project, you don’t have to create dependency

injection constructors just to make your classes testable.


Tim Rayburn is a consultant for Sogeti in the Dallas/Fort

Worth market.