2

I have MyClass and I am doing a test-class for every method (Method1Test)

public class MyClass {
    public int method1(){
        int a = method2();
        return a;
    }
    public int method2(){
        return 0;
    }
}

@RunWith(MockitoJUnitRunner.class)
public class Method1Test {
    @InjectMocks
    private MyClass myClass = new MyClass();
    @Before
    public void setup(){}
    @Test
    public void test01(){
        Mockito.when(myClass.method2()).thenReturn(25);
        int a = myClass.method1();
        assertTrue("We did it!!!",a==25);
    }
}

The problem is that I am not able to mock the call to method2 to make it return a diferent value. The Mockito sentence don't do the work.

Very thanks ^_^

Federico Piazza
  • 30,085
  • 15
  • 87
  • 123
fenix32
  • 21
  • 1
  • 1
  • 3

4 Answers4

2

You have to create a spy on the class-under-test and partially mock it by redefining the behavior for the method2() of the spy

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;


public class Method1Test {

  private MyClass myClass = new MyClass();

  @Test
  public void test01(){
    //given
    MyClass spy = spy(myClass); //create a spy for class-under-test
    when(spy.method2()).thenReturn(25); //partially override behavior of the spy
    //when
    int a = spy.method1(); //make the call to method1 of the _spy_!
    //then
    assertEquals(25, a);
  }
}

Apart from this, you don't require neither the Mockito Runner nor the @InjectMocks for your test as you're doing no injection of @Mock annotated mocks into the class-under-test.

Further, the message in the assertTrue statement is only displayed, when the condition of the assertion is NOT fulfilled. So it should be at least "We failed!!!" ;)

Gerald Mücke
  • 10,724
  • 2
  • 50
  • 67
0

In the end I find a transversal solution without create a new class (I haven't been able to do it because it is forbbiden in the actual project). I have overwrited the method in the test.

The solution is

public class MyClass {
    public int method1(){
        int a=0;
        a=method2();
        return a;
    }
    public int method2(){
        return 1;
    }
}

@RunWith(MockitoJUnitRunner.class)
public class Method1Test {
    @InjectMocks
    private MyClass myClass = new MyClass(){
        public int method2(){
            return 25;
        }
    };
    @Before
    public void setup(){}
    @Test
    public void test001(){
        Mockito.when(myClass.method2()).thenReturn(25);
        int a = myClass.method1();
        assertTrue("We did it!!!",a==25);
    }
}
fenix32
  • 21
  • 1
  • 1
  • 3
  • 1
    technically speaking, you _are_ creating a new class, though it's an anonymous one. But what you are doing now is same as writing mocks on your own as it was done in the pre-mockito era. Use a spy instead. – Gerald Mücke May 09 '16 at 12:27
  • 1
    So, In my opinion, I disagree with your solution because you only override the method in your test. Can you imagine testing different methods and overriden every one? It is awkward. – Thiago Ferreira Mar 27 '20 at 21:12
0

I tried the solution using the code below, but It didn't pass.

Mockito.when(myClass.method2()).thenReturn(25);

Afterwards, Instead of the code snippet above, I tried something different and the test passed successfully. Take a look:

Mockito.doReturn(25).when(myClass).method2();

In order to mock a test (It might be a inner method), you have to use doReturn() method.

You can use doThrow(), doAnswer(), doNothing(), doReturn() and doCallRealMethod() in place of the corresponding call with when(), for any method. It is necessary when you

  • stub void methods
  • stub methods on spy objects (see below)
  • stub the same method more than once, to change the behaviour of a mock in the middle of a test.

but you may prefer to use these methods in place of the alternative with when(), for all of your stubbing calls.

Furthermore information can be read here https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#12

Thiago Ferreira
  • 165
  • 2
  • 5
0

Instead of using mock(class) here we need to use Mockito.spy() to mock the same class we are testing. Then we can mock the method we want as follows.

@Test

  public void method1Test() { 

  MyClass myClass = new MyClass();

  MyClass myClass1 = Mockito.spy(myClass);

  Mockito.doReturn(1).when(myClass1).method2();

  Assert.assertEquals(1, myClass1.method1());

     }
 }