Friday 23 January 2009

How to Mock a Static Method

More and more i encounter places and people that still insists that static methods cant be mocked and therefore makes unit testing code which uses them harder.

Here's a very short example on how a static method CAN be mocked using the proper toolset in .Net, Java and C++. The ability to mock static methods is part of the mocking libraries I am using (Isolator for .Net, PowerMock for Jave and MockItNow for C++).

Design wise, I do NOT claim that using static methods is a good practice. In fact I am NOT a design expert, and therefore I don't have any sort of claim on what are good design practice and what are bad design practice. What I do claim is that unit tests can be written to code even if it does use static methods.

In all the examples I'll be using a class which looks something like this:

public class ClassWithStaticMethod
{
public static int StaticMethodReturnFive()
{
return 5;
}
}

.NET

[TestMethod()]
[Isolated]
public void MockStaticMethodToReturnSix()
{
Isolate.WhenCalled(() => ClassWithStaticMethod.StaticMethodReturnFive()).WillReturn(6);

int actual = ClassWithStaticMethod.StaticMethodReturnFive();
Assert.AreEqual(6, actual);
}

Java

@Test
@PrepareForTest(ClassWithStaticMethod.class)
public void MockStaticMethodToReturnSix()
{
    mockStatic(ClassWithStaticMethod.class);
    expect(ClassWithStaticMethod.StaticMethodReturnFive()).andReturn(6);
    replay(ClassWithStaticMethod.class);


    int actual = ClassWithStaticMethod.StaticMethodReturnFive();
    Assert.assertEquals(6, actual);
}

C++

TEST(MockStaticMethodToReturnSix)
{
Mocker mocker;

ClassWithStaticMethod* fake = new ClassWithStaticMethod();
REGISTER(ClassWithStaticMethod::StaticMethodReturnFive);
RECORD
{
EXPECT_RETURN_ALWAYS(ClassWithStaticMethod::StaticMethodReturnFive(),6);
}

int actual = ClassWithStaticMethod::StaticMethodReturnFive();
CHECK(6==actual);
}

1 comments:

Rogério Liesenfeld said...

Great blog!

Just for completeness, here is the JMockit version of the test:

@Test
public void mockStaticMethodToReturnSix()
{
new mockit.Expectations() {
ClassWithStaticMethod mock;

{
ClassWithStaticMethod.StaticMethodReturnFive(); returns(6);
}
}.endRecording();

int actual = ClassWithStaticMethod.StaticMethodReturnFive();
Assert.assertEquals(6, actual);
}

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Walgreens Printable Coupons