How do I check if bar(Alpha, Baz)
called bar(Xray, Baz)
using Mockito - without actually calling the later, given my MCVE class Foo
:
public class Foo {
public String bar(Xray xray, Baz baz) {
return "Xray";
}
public String bar(Zulu zulu, Baz baz) {
return "Zulu";
}
public String bar(Alpha alpha, Baz baz) {
if(alpha.get() instanceof Xray) {
return bar((Xray)alpha.get(), baz);
} else if(alpha.get() instanceof Zulu) {
return bar((Zulu)alpha.get(), baz);
} else {
return null;
}
}
}
Currently, I have roughly the following Mockito-enhanced JUnit test:
@Test
public void testBar_callsBarWithXray() {
Baz baz = new Baz(); //POJOs
Alpha alpha = new Alpha();
alpha.set(new Xray());
Foo foo = new Foo();
Foo stub = spy(foo); // Spying on Foo, as I want to call the real bar(Alpha, Baz)
// Preventing bar(Xray, Baz) from being called by providing behavior/stub
when(stub.bar(any(Xray.class), any(Baz.class))).thenReturn("ok");
// Calling the real "parent" method
stub.bar(alpha, baz);
// Testing if bar(Xray, Baz) was called by bar(Alpha, Baz)
verify(stub, times(1)).bar(any(Xray.class), any(Baz.class));
}
And it fails:
org.mockito.exceptions.verification.TooManyActualInvocations:
foo.bar(
<any>,
<any> );
Wanted 1 time:
-> at FooTest.testBar_callsBarWithXray(FooTest.java:14)
But was 2 times. Undesired invocation:
-> at FooTest.testBar_callsBarWithXray(FooTest.java:12)
I suppose it's because any(Class.class)
matches anything, and doesn't do type checking... So, from Mockito's point of view, I'm really calling bar()
twice: in Foo
and in FooTest
(on line 12).
What do I have to do to make the test do what I actually want: ensure bar(Xray, Baz)
was called when I call bar(Alpha, baz)
(while at the same time intercepting the call to bar(Xray, Baz)
)?
Using the eq()
Matcher (when(stub.bar(eq(Xray.class), any(Baz.class))...
) causes a compilation error, Cannot resolve method 'bar(Class<Xray>, Baz)'
- but then, I probably shouldn't use it that way anyway (eq(xray)
would probably be more like it)...
Also, on a related note, if I try to make the overloads of bar(Alpha, Baz)
private
, I get a compilation error for FooTest
, stating:
Error:(10, 12) java: bar(Xray,Baz) has private access in Foo
Is there a way to get round that using PowerMockito? How?
(Obviously, I only want to count the calls to bar(Xray, Baz)
- counting all calls to all overloads of bar()
is out of the question...)
Just using eq(xray)
instead of any(Xray.class)
on lines 10 and 14 of the test does the trick - but I'm not really interested in what (specific) Xray object is passed in as an argument to bar()
, as long as it's any Xray
object...
Update: I've posted a separate question for the "PowerMockito and private
methods" part of the discussion, and figured out how to make this work for public
methods; cf. my comment below.