Reputation: 583
I am trying to test a class which is creating a new object inside the constructor. I am using PowerMock with Mockito.
public ClassNeedToTest() throws Exception {
String targetCategory = "somevalue";
String targetService = "somevalue";
invoker = new ServiceInvoker(targetCategory, targetService); // throws Exception
}
For the above given code, I am trying to create a instance of ClassNeedToTest
to test different method of that class. I am not able to create the object because ServiceInvoker
creation is throwing an Exception. The ServiceInvoker
class is a third party class.
Is there any way to mock ServiceInvoker so that when test class is trying to create ClassNeedToTest
I can get the mocking object of ServiceInvoker
instead of really calling constructor of ServiceInvoker
.
In my test class is am just creating a new instance of ClassNeedToTest:
ClassNeedToTest obj = new ClassNeedToTest();
Upvotes: 6
Views: 10468
Reputation: 583
I found the answer for the same. If you follow the steps given below properly, you can mock the objects.
Step 1. - Add annotation to prepare the test class.
@PrepareForTest({ ServiceInvoker.class, ClassNeedToTest.class})
Step 2. - Mock the class.
serviceInvokerMck = Mockito.mock(ServiceInvoker.class);
Step 3. Use the below method to mock the object when new operator is called
PowerMockito.whenNew(ServiceInvoker.class).withAnyArguments().thenReturn(serviceInvokerMck);
What I was not doing was adding the class ClassNeedToTest
in PrepareForTest
annotation thinking that the only class need to be mocked should be added there.
Upvotes: 4
Reputation: 24560
Creating objects within a class' constructor is bad practice (Dependency inversion principle). A common way to get such code under test is adding a new constructor that is package private.
public ClassNeedToTest() throws Exception {
this(new ServiceInvoker("somevalue", "somevalue"));
}
ClassNeedToTest(ServiceInvoker invoker) throws Exception {
this.invoker = invoker;
}
Your tests can use the new constructor with a ServiceInvoker mock. Afterwards you can make the new constructor public and refactor your code to using only the new constructor.
Upvotes: 0