17
votes

I'm trying to write unit tests with Mockito / JUnit for a function like this:

class1 {
 method {
  object1 = class2.method // method that I want to fake the return value
  // some code that I still want to run
 }
}

Is there any way in Mockito to stub the result of class2.method? I'm trying to improve code coverage for class1 so I need to call its real production methods.

I looked into the Mockito API at its spy method but that would overwrite the whole method and not the part that I want.

3

3 Answers

7
votes

I think I am understanding your question. Let me re-phrase, you have a function that you are trying to test and want to mock the results of a function called within that function, but in a different class. I have handled that in the following way.

public MyUnitTest {
    private static final MyClass2 class2 = mock(MyClass2.class);

    @Begin
    public void setupTests() {
        when(class2.get(1000)).thenReturn(new User(1000, "John"));
        when(class2.validateObject(anyObj()).thenReturn(true);
    }

    @Test
    public void testFunctionCall() {
        String out = myClass.functionCall();
        assertThat(out).isEqualTo("Output");
    }
}

What this is doing is that within the function wrapped with the @Before annotation, I am setting up how I want the functions in class2 to respond given specific inputs. Then, from within the actual test, I am just calling the function that I am trying to test in the class I want to test. In this case, the myClass.functionCall() is running through as normal and you are not overwriting any of its methods, but you are just mocking the outputs that it gets from the methods (or method) within MyClass2.

3
votes

This Worked for Me:

public class Class1Test {

  Class1 class1;

  @Before
  public void setUp() {
    MockitoAnnotations.initMocks(this);
    class1 = new Class1();
  }

  @Test
  public void testClass1Method() {

    Class2 class2 = Mockito.mock(Class2.class);
    class1.setClass2(class2);
    Mockito.when(
            class2.class2Method(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn("some response");

    String actualResponse = class1
            .class1Method("12345", "3333", "4444");
    assertEquals("some response", actualResponse);
  }
}
1
votes

I wrote a simple example which worked fine, hope it helps:

method1() from Class1 calls method2() from Class2:

    public class Class1 {
        private Class2 class2 = new Class2();
        public int method1() {
            return class2.method2();
        }
    }

Class2 and method2() :

    public class Class2 {
        public int method2() {
            return 5;
        }
    }

And the Test:

    import org.junit.Rule;
    import org.junit.Test;
    import org.mockito.InjectMocks;
    import org.mockito.Mock;
    import org.mockito.junit.MockitoJUnit;
    import org.mockito.junit.MockitoRule;

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

    public class TestClass1 {

        @Mock
        Class2 class2;

        @InjectMocks
        Class1 class1;

        @Rule
        public MockitoRule mockitoRule = MockitoJUnit.rule();

        @Test
        public void testMethod1(){
            when(class2.method2()).thenReturn(29);
            assertEquals(29,class1.method1());
        }
    }