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:
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);
}
Post a Comment