【问题标题】:Is there a way to mock method calls on a local object有没有办法模拟本地对象的方法调用
【发布时间】:2019-10-17 07:27:08
【问题描述】:

我正在使用 Mockito 框架为现有的 spring-boot 项目编写测试用例。

在其中一个类中,他们在函数内部创建了 rest-template 的本地实例,而不是 @Autowiring

public LatxDetails getLatxCaseDetail_Fallback(String endpoint, Map<String, String> requestMap) {

//some code

RestTemplate restTemplate = new RestTemplate(); 
ResponseEntity<String> response = restTemplate.exchange(kxCreateEndpoint, HttpMethod.POST, httpEntity, String.class);

//some code

我无法模拟其余调用。我无法添加任何其他外部 jar 或更改代码。我应该如何进行?非常感谢任何帮助。

【问题讨论】:

    标签: java spring-boot junit mockito spring-boot-test


    【解决方案1】:

    显而易见的解决方案是注入 RestTemplate 而不是在本地实例化一个,但正如您所说,您不能更改现有代码,我建议使用 PowerMock with Mockito 替换 RestTemplate 的构造函数调用使用PowerMockito.whenNew 方法。

    例如

    RestTemplate restTemplateMock = Mockito.mock(RestTemplate.class);
    PowerMockito.whenNew(RestTemplate.class).withAnyArguments().thenReturn(restTemplateMock);
    

    然后在 restTemplateMock 对象上设置when

    正如 Strelok 在 cmets 中提到的:要使用 PowerMockito,您需要使用 PowerMockRunner 运行测试,方法是使用 @RunWith(PowerMockRunner.class)@PrepareForTest 注释测试类。

    例如

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(RestTemplate.class)
    public class Test {
    

    【讨论】:

    • 也许您可以扩展您的答案以注意您必须使用 PowerMockitoRunner 运行测试,并且至关重要的是您必须使用 @PrepareForTest(ClassThatCreatesTheNewInstance.class) 注释测试。对于不知道 PowerMockito 工作原理的人来说,这会省去很多麻烦。
    【解决方案2】:

    要么用 Mock 替换您的 RestTemplate,要么创建一个间谍:

    // Mock
    RestTemplate restTemplate = Mockito.mock(RestTemplate.class);
    
    // Spy
    RestTemplate restTemplate = new RestTemplate(); 
    RestTemplate spy = Mockito.spy(restTemplate);
    

    您可以像往常一样模拟exchange 方法:

    // mock
    doReturn(...).when(restTemplate).exchange(...)
    
    // spy
    doReturn(...).when(spy).exchange(...)
    

    【讨论】:

      猜你喜欢
      • 2020-07-07
      • 2020-10-23
      • 2010-09-26
      • 1970-01-01
      • 2012-06-05
      • 2016-10-23
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多