atom feed4 messages in net.java.dev.jmockit.usersRe: mocking a Singleton?
FromSent OnAttachments
Gábor LiptákJun 24, 2008 5:04 pm 
Rogerio LiesenfeldJun 25, 2008 9:22 am 
Gábor LiptákJun 25, 2008 12:52 pm 
Rogerio LiesenfeldJun 25, 2008 1:57 pm 
Subject:Re: mocking a Singleton?
From:Rogerio Liesenfeld (java@yahoo.com)
Date:Jun 25, 2008 1:57:35 pm
List:net.java.dev.jmockit.users

Ok, so you also need to mock the getInstance method. Below I will show how to do
that, but first let me clarify that JMockit Core (and JMockit Annotations) only do method
redefinition, without changing any class type or any method/constructor signature. What this
means is that you, as the client programmer, will provide an alternative (mock) implementation
for each method/constructor redefined, and in this implementation you can make use of any
Java language/platform feature, nothing more. So, in the case of a Singleton class
which only have private constructors, you would have to use reflection to make a constructor
accessible before using it to create a new instance.

The best way to solve your problem would be to use JMockit Expectations, which
can instantiate a mock instance even when there is no public constructor. The
following code (which I tested with JUnit 4.4 and JDK 1.6) shows a simple test that
demonstrates it.

Singleton.java: <code> public class Singleton { private Singleton() {}

private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); }

public static Singleton getInstance() { System.out.println("This should not be printed"); return SingletonHolder.INSTANCE; }

public int getValue() { return 1; } } </code>

SingletonTest.java: <code> import mockit.*; import static org.junit.Assert.*; import org.junit.*;

public class SingletonTest { @Test public void createMockSingletonInstance() { new Expectations(true) { Singleton singleton;

{ Singleton.getInstance(); returns(singleton); singleton.getValue(); returns(2); } };

int value = Singleton.getInstance().getValue(); assertEquals(2, value); } } </code>

Therefore, it IS actually possible to mock a static method returning an instance
of the original class, just as you originally asked.