0

Given a abstract class

public abstract class ClassA
{

   protected String getName()
   {
    return "my name"
   }

}

public class ClassB extends ClassA{
   public String doSomething(){
     String name = getName();
     return name + " cool ";
   }
}

public class TestClass { 

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

     @Test public void testDoSomething() { 
          ClassB b = new ClassB();
          b.doSomething();
     } 
} 

How to mock getName() and return a specific value while writing test for doSomething method for classB.

Aki
  • 55
  • 1
  • 1
  • 8

4 Answers4

1

The same way you'd mock a concrete class. Use the @Mock annotation next to the property in your test class.

@Mock
private ClassA mockClassA;

Then use the

doReturn("mockname").when(mockClassA).getName()

here you can find more details.

fpezzini
  • 774
  • 1
  • 8
  • 17
  • I did exactly this but still call is going to the function – Aki May 18 '20 at 12:06
  • This is the code I have and it does not call the method. Variable bla has null value which means it never got into the mocked class' method: ` public class TestClass { @Mock private ClassA mockClassA; @Before public void setUp() { MockitoAnnotations.initMocks(this); } @Test public void testGetName() { String bla = mockClassA.getName(); System.out.println(bla); } } abstract class ClassA { protected String getName() { return "my name"; } }` – fpezzini May 18 '20 at 12:16
  • when i call doSomething() function from my test, will the getName() function value will return me null or the specified value which i set ? – Aki May 18 '20 at 12:36
  • @Aki This is because you are mocking the method on a different instance instead of an actual one. Refer my answer if that helps – Ratish Bansal May 18 '20 at 12:56
  • @RatishBansal I tried your too , is said when should be applied on mock – Aki May 18 '20 at 12:58
  • @RatishBansal Getting this error . [ Argument passed to when() is not a mock! ] – Aki May 18 '20 at 13:06
  • @Aki I have updated answer to address the issue you mentioned and its working for me locally as well – Ratish Bansal May 18 '20 at 13:44
  • @Aki did you do initialize Mocks in the setup method? see above the setUp method: `@Before public void setUp() { MockitoAnnotations.initMocks(this); }` – fpezzini May 18 '20 at 15:32
1
@Test
public void testcase() {
    ClassB classB= spy(ClassB.class);
    when(classB.getName()).thenReturn(""); 
    classB.doSomething();

}
Ratish Bansal
  • 1,982
  • 1
  • 10
  • 19
  • @Aki Actually we need to spy the class. Could you try this and see if it works. The spy will make sure the mocked implementations are called if provided, other the actual code. – Ratish Bansal May 18 '20 at 13:28
0
@Test
public void testcase() {
    ClassB b = mock(ClassB.class);
    doReturn("new name").when(b).getName();
}
  • Hi, welcome to Stack Overflow! Just for you to know: when you answer a question try to post something more complete than just the code, maybe add a little explanation of what was the author's error and how you fixed it. I'm telling you this because your answer has been flagged for deletion in the "Low Quality Post" queue. You can edit your answer using the "Edit" button , or by clicking here: [edit] – Federico Grandi May 18 '20 at 17:09
0

You can use a spy instead of a mock. This way you can use an existing instance of ClassB you have prepared earlier:

ClassB classB = PowerMockito.spy(new ClassB());
PowerMockito.when(classB, method(ClassB.class, "getName")).withNoArguments()
            .thenReturn("your name");

It can also be declared using @Spy.