1

Here am try to spy a method In that its externally calls another method. All I need is to mock the external method. Below is my simulation of my project kind of legacy project

public class TestClass {
    public int dependencyOne(){
        System.out.println("Need to mock Externally ");
        return  100;
    }
    public int methodNeedTobeTested(int a){
        int c = new AnotherClass().dependencyTwo();
        return a + this.dependencyOne() + c;
    }
}

public class AnotherClass {
    public int dependencyTwo(){
        System.out.println("Need to mock externally");
        return 100;
    }
}

Here is my Test Case

public class TestClassTest {
    @InjectMocks
    TestClass testClass;

    @Mock
    AnotherClass anotherClass;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }

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

    @Test
    public void methodNeedTobeTested() {
        testClass = Mockito.spy(new TestClass());
        Mockito.when(anotherClass.dependencyTwo()).thenReturn(10);
        Mockito.doReturn(10).when(testClass).dependencyOne();
        assertEquals(testClass.methodNeedTobeTested(10),30);
    }
}

My Output :

Need to mock externally

java.lang.AssertionError: Expected :30 Actual :120

what am Missing?

Dependency :

byte-buddy-1.10.11.jar
cglib-nodep-3.2.9.jar
hamcrest-core-1.3.jar
javassist-3.24.0-GA.jar
junit-4.12.jar
mockito-all-1.10.19.jar
mockito-core-2.23.0.jar
objenesis-3.0.1.jar

1 Answer 1

1

To mock the call to the AnotherClass, you should not create an instance using new inside your application code. This will always instantiate the real object and you are not able to mock it.

A better approach would be to take an instance of AnotherClass as part of the constructor of TestClass and follow inversion of control (e.g. use the Spring Framework of CDI to have dependency injection).

public class TestClass {

    public AnotherClass anotherClass;

    public TestClass(AnotherClass anotherClass) {
       this.anotherClass = anotherClass;
    }

    public int dependencyOne(){
        System.out.println("Need to mock Externally ");
        return  100;
    }

    public int methodNeedTobeTested(int a){
        int c = anotherClass.dependencyTwo();
        return a + this.dependencyOne() + c;
    }
}

With this approach your test should work.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the suggestion , But with the help of PowerMockito , I can able to mock this or Is powermockito is bad practice ?
A more clean approach would be to follow inversion of control and make use of dependency injection. I see PowerMockito as a bad practice most likely as this allows bad design of your application

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.