Reputation: 2883
public class MainClass {
public void makeCall() {
CustomObject obj = new CustomObject();
obj.testMethod();
}
}
I want to unit test the makeCall()
. So i have to mock the CustomObject
in the above sample. I am using Mockito as the mock framework.But when i mock the object like mock(CustomObject.class)
. makeCall()
method always call the actual object not the mocked one.Is there anyway to mock the local objects. Please help
Upvotes: 3
Views: 7432
Reputation: 121710
Not with Mockito proper, no. You have to modify your code so that you create your custom object from another source and mock that source.
This is what I'd recommend... However there does exist a solution with PowerMockito:
final CustomObject obj = mock(CustomObject.class);
PowerMockito.whenNew(CustomObject.class).withNoArguments()
.thenReturn(obj);
However, uh. Refactor your code. You'll be all the better for it.
Upvotes: 0
Reputation: 30528
Short answer is no. What you can do is to refactor the local object to a field or a parameter like this:
public class MainClass {
public void makeCall(CustomObject obj) {
obj.testMethod();
}
}
Your current program violates the Dependency Inversion Principle so it is advised to refactor it anyway.
If you make the field an instance variable you can mock it easily if you have a setter or you initialize it based on a constructor parameter. Example for the latter:
public class MyTest {
@Mock
private CustomObject objMock;
private MyClass objToTest;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
objToTest = new MyClass(objMock);
}
}
Upvotes: 1
Reputation: 40036
A unit-test-friendly version of your MainClass
should have CustomObject
injected, for example:
public class MainClass {
private CustomObject customObject = new CustomObject(); // a default one if none is provided
public void setCustomObject(CustomObject customObject) {
this.customObject = customObject;
}
public void makeCall() {
this.customObject.testMethod();
}
}
and your test will look like:
CustomObject mockCustomObject = mock(CustomObject.class);
when(mockCustomObject.testMethod()).thenReturn(...);
MainClass sut = new MainClass();
sut.setCustomObject(mockCustomObject);
sut.makeCall();
verify(mockCustomObject).testMethod();
With Mockito's annotation, it can be further simplified as:
public class MyClassTest {
@InjectMocks
private MainClass mainClass;
@Mock
private CustomObject mockCustomObject;
@Before
public void setup() {
MockitoAnnotations.initMocks(this); // or use mockito runner
}
@Test
public void testMakeCall() {
when(mockCustomObject.testMethod()).thenReturn(...);
mainClass.makeCall();
verify(mockCustomObject).testMethod();
}
}
Upvotes: 4