auser
auser

Reputation: 7547

How to mock a single method in java

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

Answers (5)

magiccrafter
magiccrafter

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

Konstantin Pribluda
Konstantin Pribluda

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

John B
John B

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.

Mockito.spy()/@Spy

Upvotes: 88

Michael Borgwardt
Michael Borgwardt

Reputation: 346397

You could simply create a subclass of A that overrides method1().

Upvotes: -3

npe
npe

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

Related Questions