I have run into a problem using PowerMock where I feel forced to create ugly code if I want to return a mocked item only once. As an example I have the following code:
mockMap = spy(new HashMap());
HashMap<String, String> normalMap = new HashMap<>();
HashMap<String, String> normalMap2 = new HashMap<>();
HashMap<String, String> normalMap3 = new HashMap<>();
whenNew(HashMap.class).withNoArguments()
.thenReturn(normalMap)
.thenReturn(mockMap)
.thenReturn(normalMap2)
.thenReturn(normalMap3);
This of course works, but it feels very clunky, especially as I need to create a new hashmap for every new call.
So my question is: is there a way to tell PowerMock that it should stop interfering after a set amount of calls?
edit: After reading the answers, I got the following:
final AtomicInteger count = new AtomicInteger(0);
whenNew(HashMap.class).withNoArguments().thenAnswer(invocation -> {
switch (count.incrementAndGet())
{
case 1:
return mockMap;
default:
return new HashMap<String, String>();
}
});
However it gives me a StackOverFlowError using the following code:
describe("test", () -> {
beforeEach(() -> {
mockStatic(HashMap.class);
final AtomicInteger count = new AtomicInteger(0);
whenNew(HashMap.class).withNoArguments().thenAnswer(invocation ->
{
switch (count.incrementAndGet())
{
case 5:
return mockMap;
default:
return new HashMap<String, String>();
}
});
});
it("Crashes on getting a new HashMap", () -> {
HashMap map = new HashMap<>();
map.put("test", "test");
HashMap normal = new HashMap<String, String>();
expect(normal.containsValue("test")).toBeTrue();
});
});
Worth noting is that I don't have a mockStatic(HashMap.class) in my larger tests that get the same errors(which I get rid of if I remove the mockStatic call)
A solution that works(but feels like a workaround) is building on that by editing the default statement into:
default:
normalMap.clear();
return normalMap;