java Mockito:如何替换被测类调用的类的方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17000473/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mockito: How to replace method of class which is invoked by class under test?
提问by Bevor
Unfortunately the Mockito documentation lacks of exhaustive information, it's difficult to find the proper way how to create the following setup.
不幸的是 Mockito 文档缺乏详尽的信息,很难找到如何创建以下设置的正确方法。
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 notinvoke 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).
我有一个应该测试的类“ResourceManager”。这个类实例化了另一个类“JerseyClient”,它有一个名为“get”的方法。我希望“ResourceManager”不要调用真正的“JerseyClient”,而是从中调用模拟(或存根?)(我已经不清楚在 Mockito 上下文中模拟和存根或模拟和间谍之间有什么区别)。
My attempts are to @Mock (or @Spy?) JerseyClient, or at least one method of it:
我的尝试是@Mock(或@Spy?)JerseyClient,或至少它的一种方法:
@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:
如您所见,我尝试模拟 jerseyClient.get() 方法以返回预定义的 JSON 字符串:
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.
但它们都不起作用。这意味着调用了真正的 JerseyClient.get 方法,因为它尝试使用真正的 JerseyClient 发出 HTTP 请求。
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?
什么是解决方案,我想在这里做什么?它是在监视一个真实的对象还是在我想模拟它的方法的地方模拟一个对象,我什么时候可以替换方法,只在模拟上还是只在间谍上?
采纳答案by Bevor
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.
我也可以使用“doReturn...when”模式。