Brendan Enrick's Blog

Daily Software Development.


Static Mocking with JustMock

by Brendan Enrick Friday, March 23 2012 11:00

One of the coolest (and scariest) things I’ve seen lately is mocking static classes and methods with JustMock. I was working on some legacy code, and was making some changes, so I wanted to make sure that I got everything tested first. When I went to write the tests, I noticed that I needed to wrap and hide away a static method that was being called.

My eventual intent, however, is to get rid of the static class and method calls if possible. Writing the wrapper around it temporarily, so I can get tests in place before refactoring has always seemed like a pain. I went to check and see if JustMock would be able to mock a static class. That seemed like one of those crazy things that commercial mocking frameworks can usually do. I was right. It could mock the static class. (SCARY!!)

I wrote some code that looked like this: (Sorry I can’t show you my clients’ code in my blog without their permission, so you get sample code.)

public static class MyStaticClass
{
    public static int DoSomeDependentStuffThatIsHardToFix()
    {
        // Pretend this does more than just returning 1
        return 1;
    }
}

 

In my example, I need to test some code calling this static method. Normally, I would put a wrapper around this class, write my tests, refactor, and eventually change this to not be a static dependency anymore.

I decided to try this. Here is a test class that uses mocking to demonstrate how I can decide any result for this method and have control of this dependency. Notice that my method always returns 1. Pretend that a different result were possible.

Now when I go to write my test, I can just Mock out the static and define that I want that method to be called and for it to return 2 instead of 1. I will then assert that it worked as I expected in my test. Once I confirm that the mock works as expected using this type of test, I can put it in place in my actual test. (Yes, I sometimes write temporary tests to confirm what I expect before I write the whole test. Little steps.)

[TestFixture]
public class MyTestClass
{
    [Test]
    public void WhatIsTestedDoesNotMatter()
    {
        Mock.SetupStatic(typeof(MyStaticClass));
 
        Mock.Arrange(() => MyStaticClass.DoSomeDependentStuffThatIsHardToFix()).Returns(2);
 
        Assert.AreEqual(2, MyStaticClass.DoSomeDependentStuffThatIsHardToFix());
    }
}

Then when I go and run my tests, I get this nice result showing me that everything is working as I expect it to. Yippee!

JustMock Static Test Passing

How it achieves this? I am not sure. I intend to find out though. When I do, I will write a post explaining it.

Have a good day!

Comments

3/24/2012 10:34:42 AM #

Ken

I looked at this a while ago and I think you should have stressed the fact that if you have to mock something static you generally have a design flaw. I mean you mentioned that this was legacy code and you plan to refactor but when I watched Telerik's demo on it they made it sound like it was the missing link of Mocking which it isn't. The reason mocking frameworks (Moq, Rhino) don't mock static methods is because they are generally a bad design decision.

That aside - I think a great blog post would be "Look Mom! No ctor, when static classes make sense!".

Ken United States

3/25/2012 6:39:57 PM #

Brendan Enrick

@Ken Yes, I completely agree. The time to use these is when there is a design flaw with the code.

The cool thing about this, however, is that I was able to test the code before doing the refactoring. I try to make sure that I test my code before refactoring. Occasionally, I need to make minor changes.

This lets me test earlier, since I don't have to refactor the static yet. Without the ability to mock the static, I would have needed to refactor without unit tests.

Brendan Enrick United States

3/27/2012 3:08:27 PM #

Erik

I've never used JustMock before (I use Moq), but I've recently been doing some stuff in Java and using a tool called PowerMock.  The setup code you have there is similar enough to PowerMock for statics that I wonder if one didn't use the other as a rough API guideline.

I definitely agree with the "scary" part.  I think that a lot of people who favor static/procedural code will look at this and conclude that there's no downside to using static if you can just 'mock' it out for testing.  There's something good about the pain of trying to test a codebase with a lot of statics -- like the sting of antiseptic on a cut.

Erik United States

3/27/2012 3:39:41 PM #

Eli

I think the actual reason that Moq and Rhino don't mock statics is because they're based on Castle. TypeMock Isolator stood relatively alone for a while in its ability to mock these types of things because it actually intercepts calls as they are occurring and redirects them (I can't speak to JustMock, I haven't looked into it).

That said, I'd be interested to know if you tried this to mock an extension method (or better yet, an extension method on an interface).

Eli United States

Comments are closed