Mock an object inside a method in JUnit

11,257

If the method is protected then you dont need to use Powermockito, plain vanilla Mockito is enough and spying would do the trick here. Assuming the test class is in the same package as the production one, just in the src/test/java dir.

ClassUnderTest classUnderTestSpy = Mockito.spy(new ClassUnderTest()); // spy the object 

ObjectMetadata objectMetadataToReturn = new ObjectMetadata();

doReturn(objectMetadataToReturn).when(classUnderTestSpy).get(Mockito.any(String.class));

I used any() matcher for the input but you can use a concrete value also.

Update If you cannot see the method then you would need to create an inner class that extends the prod one, implement the get method:

public class Test{

  ObjectMetadata objectMetadataToReturn = new ObjectMetadata();

  @Test
  public void test(){
      ClassUnderTestCustom classUnderTestCustom  = new ClassUnderTestCustom();

      // perform tests on classUnderTestCustom  
  }

  private class ClassUnderTestCustom extends ClassUnderTest{

     @Override
     public String getMetadata(String path){
        return objectMetadataToReturn ;
     }
  }

}
Share:
11,257

Related videos on Youtube

pac
Author by

pac

Developer/tester. Enjoy most sports.

Updated on June 04, 2022

Comments

  • pac
    pac almost 2 years

    I'm trying to get to grips with JUnit & Mockito etc.

    I currently have a method with the below line.

    ObjectMetadata metadata = getMetadata(path.toString());
    

    Is there any way I can mock it? I've tried things like the below

    Whitebox.setInternalState(<mock of class>, "metadata", "abc");
    

    but I just get

    org.powermock.reflect.exceptions.FieldNotFoundException: No instance field named "metadata" could be found in the class hierarchy of com.amazonaws.services.s3.model.ObjectMetadata.

    I think it's because previous use of Whitebox.setInternalState was with variables.

    Any info. that might get me started would be appreciated.

  • pac
    pac over 6 years
    Thanks Sanveet. Does the fact that getMetadata() is protected change anything? I'm getting an error saying "unable to view protected method".
  • Sanjeev Kumar
    Sanjeev Kumar over 6 years
    if method getMetadata() is protected method then we need to use reflection API in junit to call that method like below example: Class<?> clazz = mockObjectMetadata.getClass(); Method method = clazz.getDeclaredMethod("getMetadata", String.class); method.setAccessible(true); mockObjectMetadata = (ObjectMetadata) method;
  • pac
    pac over 6 years
    Is there no way of getting that to work if the test is in a different package? My test is in com.in.stock.sf.col.tests while the production is in com.in.stock.sf.col.
  • Maciej Kowalski
    Maciej Kowalski over 6 years
    any reason why you not using src/main/java for prod and /src/test/java for testing? and then usnig the same package structure in each?
  • pac
    pac over 6 years
    Sorry, I should have been clear. com.in.stock.sf.col is in src/main/java and com.in.stock.sf.col.tests is in /src/test/java. As for why the sub levels differ, I'm not sure as it was setup by somebody else.
  • Maciej Kowalski
    Maciej Kowalski over 6 years
    well in theory your Test can extend the prod class and you will have access to that method. Still the proper structure would be the way to go though..
  • Maciej Kowalski
    Maciej Kowalski over 6 years
    basically if you want to stay with that structure then check my update
  • pac
    pac over 6 years
    Cheers Maciej. I've moved the file up a level to com.in.stock.sf.col.tests so its working. As an after thought I was thinking is it possible to create a file which contains all the mocks and have it at com.in.stock.sf.col and have a different file with my tests at com.in.stock.sf.col.tests? I'll experiment with it a little when I get some time.