Search code examples
javatestingjunitmockitostub

how to stub a method in a class which is called from another class


public class A {
    .
    .
    .
    public static String methodA() {
        String x = new B().methodX();
        return x + "how are ya?";
    }
}
public class B {
    .
    .
    public String methodX() {
        return "Hello!";
    }
}

@Test
public void testGreeting() {
    final B b = Mockito.spy(new B());
    Mockito.when(b.methodX()).thenReturn("Hi!");

    String greetings = A.methodA();
    // greetings -> "Hello" but i want it to be "Hi!".
}

I'm not able to get my method to return the desired value. Above implementations shows how I have written my test, but it's not working.

What am i doing wrong here?


Solution

  • Yet to clarify given answers: your mistake is that you do not actually use that spy/mock anywhere.

    In your class A you have a static method where a new B is always instantiated instead of using your spy:

    String x = new B().methodX();
    

    Spy does not make class somehow globally spied but creates just one instance that is spied and can be mocked. And yet again: this new B() is not a spy nor mock.

    One possible working solution would be to change your design a bit (as already suggested) and let Mockito inject this spied B in an instance of A:

    @RunWith(MockitoJUnitRunner.class)
    public class TestClass {
    
        public static class AlternativeA {
            // this B can be injected and replaced with a spy or mock
            private B b = new B();
            // get rid of static to use spied B
            public String methodA() {
                String x = b.methodX();
                return x + "how are ya?";
            }
        }
    
        // Using annotations to create and inject mocks
        @Spy
        private B b;
        @InjectMocks
        private AlternativeA a;
        
        @Test
        public void testGreeting() {
            Mockito.when(b.methodX()).thenReturn("Hi!");
            String greetings = a.methodA();
        }
    }