Created
November 12, 2011 15:27
-
-
Save davelnewton/1360685 to your computer and use it in GitHub Desktop.
Stupid singleton is stupid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class UsesLongRunningCtor { | |
/** Retrieves data and returns processed result. */ | |
public String transformData() { | |
// LongRunningCtor "embedded"; direct reference, like a static utility class. | |
String rawData = LongRunningCtor.instance().fetch(); | |
return rawData.replace("Raw", "Processed"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Pseudo-singleton with a slow constructor. Don't make singletons like this. */ | |
public class LongRunningCtor { | |
private static final LongRunningCtor INSTANCE = new LongRunningCtor(); | |
private LongRunningCtor() { | |
try { Thread.sleep(60 * 1000); } | |
catch (InterruptedException e) { e.printStackTrace(); } | |
} | |
public String fetch() { return "Raw data"; } | |
public static LongRunningCtor instance() { return INSTANCE; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Slow test is slow. Calls undecorated singleton. */ | |
@Test | |
public void testSlowSingleton() { | |
long start = System.currentTimeMillis(); | |
UsesLongRunningCtor underTest = new UsesLongRunningCtor(); | |
assertEquals("Processed data", underTest.transformData()); | |
long end = System.currentTimeMillis(); | |
out.println("Unmocked test time ~" + (end - start) / 1000.0 + " seconds."); | |
} | |
// Output is ~ "Unmocked test time ~60.0 seconds." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@RunWith(PowerMockRunner.class) | |
@PrepareForTest(LongRunningCtor.class) | |
public class TestWithoutCtor { | |
@Test | |
public void testSlowSingleton() { | |
long start = System.currentTimeMillis(); | |
// Suppress ctor *before* createPartialMock and static mock, or ctor is run. | |
suppress(constructor(LongRunningCtor.class)); | |
// Could also do mockStaticPartial(LongRunningCtor.class, "instance"). | |
mockStatic(LongRunningCtor.class); | |
// Could also do createPartialMock(LongRunningCtor.class, "fetch"). | |
LongRunningCtor mock = createMock(LongRunningCtor.class); | |
expect(LongRunningCtor.instance()).andReturn(mock); | |
expect(mock.fetch()).andReturn("Processed data"); | |
replayAll(mock); | |
UsesLongRunningCtor underTest = new UsesLongRunningCtor(); | |
assertEquals("Processed data", underTest.transformData()); | |
long end = System.currentTimeMillis(); | |
verify(mock); | |
out.println("Unmocked test time ~" + (end - start) / 1000.0 + " seconds."); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<dependency> | |
<groupId>cglib</groupId> | |
<artifactId>cglib</artifactId> | |
<version>2.2.2</version> | |
</dependency> | |
<dependency> | |
<groupId>junit</groupId> | |
<artifactId>junit</artifactId> | |
<version>4.5</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.powermock</groupId> | |
<artifactId>powermock-module-junit4</artifactId> | |
<version>${powermock.version}</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.powermock</groupId> | |
<artifactId>powermock-api-easymock</artifactId> | |
<version>${powermock.version}</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.easymock</groupId> | |
<artifactId>easymock</artifactId> | |
<version>3.1</version> | |
</dependency> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment