Mock an object inside a method in JUnit
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 ;
}
}
}
Related videos on Youtube
Comments
-
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 over 6 yearsThanks Sanveet. Does the fact that getMetadata() is protected change anything? I'm getting an error saying "unable to view protected method".
-
Sanjeev Kumar over 6 yearsif 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 over 6 yearsIs 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 over 6 yearsany 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 over 6 yearsSorry, 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 over 6 yearswell 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 over 6 yearsbasically if you want to stay with that structure then check my update
-
pac over 6 yearsCheers 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.