Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested method mocking in Mockito

I have the following Java classes:

public class A
{
    @Autowired
    private B b;
    public int aFn()
    {
        int something = b.bFn();
    }
}
public class B
{
    @Autowired
    private C c;
    public int bFn()
    {
        int something = c.cFn();
    }
}
public class C
{
    public int cFn()
    {
        return 231;
    }
}

And the following test using Mockito to test the above code:

public class test
{
    @Autowired
    private A a;

    private C c;

    @Test
    public void testA()
    {
        c = mock(C.class);
        when(c.cFn(),anyInt()).thenReturn(something);
        assertEquals(0, a.aFn());
    }
}

When I debug testA, I find that real c.Cfn() gets executed, not the mocked one. Is there anything what I am doing incorrectly here? Please help!

like image 657
user1471283 Avatar asked Aug 21 '13 15:08

user1471283


1 Answers

First of all, you should always mock the direct dependencies of an object, and not its transitive dependencies. So you should mock B, and not C, to test A. Then you would write a unit test for B by mocking C.

Second: you're not injecting the mock anywhere in the unit test. What you should have is:

public class Test {

    // not autowired here
    private A a;

    private B mockB;

    @Test
    public void testA() {
        mockB = mock(B.class);
        when(b.bFn(), anyInt()).thenReturn(something);

        // the missing part: injecting the mock into the tested object
        a = new A(mockB);
        // or a = new A();
        //    a.setB(mockB);

        assertEquals(0, a.aFn());
    }
}

When you use mock(B.class), you get one mock instance of B. That doesn't mean that all the other instances of B will do what the mock does.

Mocking C to test A is a bad practice: unit tests should test one class in isolation of the others. But if you really want that, then create a mock C, create a B and inject the mock C inside it, then create an A and inject the B inside it.

A --> B --> mockC
like image 159
JB Nizet Avatar answered Sep 28 '22 05:09

JB Nizet