Unfortunately the Mockito documentation lacks of exhaustive information, it's difficult to find the proper way how to create the following setup.
I have a class "ResourceManager" which should be tested. This class instantiates another class "JerseyClient" which has a method called "get". I want "ResourceManager" to not invoke the real "JerseyClient" but a mock (or a stub?) from it (It's already unclear to me what is the difference between mocking and stubbing or mocks and spies in Mockito context).
My attempts are to @Mock (or @Spy?) JerseyClient, or at least one method of it:
@RunWith(MockitoJUnitRunner.class)
public class ResourceManagerTest
{
@Mock
private JerseyClient jerseyClient;
@Test
public void testResultHandling() throws JsonGenerationException, JsonMappingException, IOException, ResourceException
{
TestEntity testEntity = new TestEntity();
ResourceManager resourceManager = new ResourceManager();
testEntity.setGet(true);
testEntity.setTestAttribute("1stTest");
when(jerseyClient.get(anyString())).thenReturn("{\"get\":true,\"testAttribute\":\"2ndTest\",\"message\":\"success\"}");
// doReturn("{\"get\":true,\"testAttribute\":\"2ndTest\",\"message\":\"success\"}").when(jerseyClient).get(anyString());
TestEntity result = (TestEntity)resourceManager.execute(testEntity, TestEntity.class);
assertThat(result, is(notNullValue()));
assertThat(result.getMessage(), is("success"));
assertThat(result.getTestAttribute(), is("2ndTest"));
}
}
As you can see, I tried to mock jerseyClient.get() method to return a predefined JSON string:
when(jerseyClient.get(anyString())).thenReturn("{\"get\":true,\"testAttribute\":\"2ndTest\",\"message\":\"success\"}");
or
doReturn("{\"get\":true,\"testAttribute\":\"2ndTest\",\"message\":\"success\"}").when(jerseyClient).get(anyString());
But none of them work. That means that the real JerseyClient.get method is invoked, because it tries to make a HTTP request with the real JerseyClient.
What is the solution and what is this what I want to do here? Is it spying on a real object or mocking an object where I want to mock a method of it, and when can I replace methods, only on mocks or only on spies?
Instead of using mock(class) here we need to use Mockito. spy() to mock the same class we are testing. Then we can mock the method we want as follows. Mockito.
Mockito allows us to partially mock an object. This means that we can create a mock object and still be able to call a real method on it. To call a real method on a mocked object we use Mockito's thenCallRealMethod().
@Mock is used to create mocks that are needed to support the testing of the class to be tested. @InjectMocks is used to create class instances that need to be tested in the test class. Annotated class to be tested dependencies with @Mock annotation.
A stub is a fake class that comes with preprogrammed return values. It's injected into the class under test to give you absolute control over what's being tested as input. A typical stub is a database connection that allows you to mimic any scenario without having a real database.
I found the answer on my own. I need to add
@InjectMocks
private ResourceManager resourceManager;
Then I need to run the test with this instance:
@RunWith(MockitoJUnitRunner.class)
public class ResourceManagerTest
{
@Mock
private JerseyClient jerseyClient;
@InjectMocks
private ResourceManager resourceManager;
@Test
public void testResultHandling() throws JsonGenerationException, JsonMappingException, IOException, ResourceException
{
TestEntity testEntity = new TestEntity();
testEntity.setGet(true);
testEntity.setTestAttribute("1stTest");
when(jerseyClient.get(anyString())).thenReturn("{\"get\":true,\"testAttribute\":\"2ndTest\",\"message\":\"success\"}");
TestEntity result = (TestEntity)resourceManager.execute(testEntity, TestEntity.class);
assertThat(result, is(notNullValue()));
assertThat(result.getMessage(), is("success"));
assertThat(result.getTestAttribute(), is("2ndTest"));
}
}
And I can also use the "doReturn...when" pattern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With