Reputation: 7547
Is it possible to Mock a single method of a Java class?
For example:
class A {
long method1();
String method2();
int method3();
}
// in some other class
class B {
void someMethod(A a) {
// how would I mock A.method1(...) such that a.method1() returns a value of my
// choosing;
// whilst leaving a.method2() and a.method3() untouched.
}
}
Upvotes: 44
Views: 96967
Reputation: 5484
Based on Mockito's documentation the accepted answer is not the correct way to Spy real objects.
The right way to do this is to use the following pattern:
doReturn("foo").when(spy).get(0);
Below you can find the snippet from Mockito's about Spying on real objects.
Important gotcha on spying real objects!
Sometimes it's impossible or impractical to use when(Object) for stubbing spies. Therefore when using spies please consider doReturn|Answer|Throw() family of methods for stubbing. Example:List list = new LinkedList(); List spy = spy(list); //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty) when(spy.get(0)).thenReturn("foo"); //You have to use doReturn() for stubbing doReturn("foo").when(spy).get(0);
Mockito does not delegate calls to the passed real instance, instead it actually creates a copy of it. So if you keep the real instance and interact with it, don't expect the spied to be aware of those interaction and their effect on real instance state. The corollary is that when an unstubbed method is called on the spy but not on the real instance, you won't see any effects on the real instance. Watch out for final methods. Mockito doesn't mock final methods so the bottom line is: when you spy on real objects + you try to stub a final method = trouble. Also you won't be able to verify those method as well.
Upvotes: 6
Reputation: 12367
Assuming you are using jmockit:
public void testCase(@Mocked("methodToBeMocked") final ClassBoBeMocked mockedInstance) {
new Expectations() {{
mockedInstance.methodToBeMocked(someParameter); returns(whateverYouLikeItToReturn);
}}
mockedInstance.callSomemethod();
}
Upvotes: 1
Reputation: 32969
Use Mockito's
spy mechanism:
A a = new A();
A aSpy = Mockito.spy(a);
Mockito.when(aSpy.method1()).thenReturn(5l);
The use of a spy calls the default behavior of the wrapped object for any method that is not stubbed.
Upvotes: 88
Reputation: 346397
You could simply create a subclass of A
that overrides method1()
.
Upvotes: -3
Reputation: 15709
Use the spy()
method from Mockito, and mock your method like this:
import static org.mockito.Mockito.*;
...
A a = spy(new A());
when(a.method1()).thenReturn(10L);
Upvotes: 8