gpt4 book ai didi

RestTemplate 和 RetryTemplate 的 JAVA Mockito 单元测试

转载 作者:行者123 更新时间:2023-11-30 01:54:34 30 4
gpt4 key购买 nike

我目前正在为以下方法编写单元测试

@Autowired
private RequestConfig requestConfig;

@Autowired
private RetryTemplate retryTemplate;

public ResponseEntity<String> makeGetServiceCall(String serviceUrl) throws Exception {
try {
return retryTemplate.execute(retryContext -> {

RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = requestConfig.createHttpHeaders();
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> response = restTemplate.exchange(serviceUrl, HttpMethod.GET, entity, String.class);
return response;

});
} catch (Exception e) {
throw new Exception("Generic exception while makeGetServiceCall due to" + e + serviceUrl);
}
}

更新的方法:

@Autowired
private RequestConfig requestConfig;

@Autowired
private RetryTemplate retryTemplate;

@Autowired
private RestTemplate restTemplate;

public ResponseEntity<String> makeGetServiceCall(String serviceUrl) throws Exception {
try {
return retryTemplate.execute(retryContext -> {

HttpHeaders headers = requestConfig.createHttpHeaders();
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> response = restTemplate.exchange(serviceUrl, HttpMethod.GET, entity, String.class);
return response;

});
} catch (Exception e) {
throw new Exception("Generic exception while makeGetServiceCall due to" + e + serviceUrl);
}
}

我尝试了所有的可能性,但我无法做到正确。这是我的以下测试。

@Mock
private RestTemplate restTemplate;

@Mock
public RequestConfig requestConfig;

@InjectMocks
private RetryTemplate retryTemplate;

ServiceRequest serviceRequest;


@Test
public void makeGetServiceCall() throws Exception {
String url = "http://localhost:8080";
RetryTemplate mockRetryTemplate = Mockito.mock(RetryTemplate.class);
RestTemplate mockRestTemplate = Mockito.mock(RestTemplate.class);
ResponseEntity<String> myEntity = new ResponseEntity<>(HttpStatus.ACCEPTED);
Mockito.when(mockRetryTemplate.execute(ArgumentMatchers.any(RetryCallback.class), ArgumentMatchers.any(RecoveryCallback.class), ArgumentMatchers.any(RetryState.class))).thenReturn(myEntity);

Mockito.when(mockRestTemplate.exchange(
ArgumentMatchers.eq(url),
ArgumentMatchers.eq(HttpMethod.GET),
ArgumentMatchers.<HttpEntity<String>>any(),
ArgumentMatchers.<Class<String>>any())
).thenReturn(myEntity);

ResponseEntity<String> response = serviceRequest.makeGetServiceCall(url);
Assert.assertEquals(myEntity, response);
}

更新的测试用例:

 @Mock
public RequestConfig requestConfig;

@Mock
private RestTemplate restTemplate;

@Mock
private RetryTemplate retryTemplate;

@InjectMocks
ServiceRequest serviceRequest;

@Test
public void makeGetServiceCall() throws Exception {
//given:
String url = "http://localhost:8080";

when(requestConfig.createHttpHeaders()).thenReturn(null);
ResponseEntity<String> myEntity = new ResponseEntity<>( HttpStatus.ACCEPTED);
when(retryTemplate.execute(any(RetryCallback.class), any(RecoveryCallback.class), any(RetryState.class))).thenAnswer(invocation -> {
RetryCallback retry = invocation.getArgument(0);
return retry.doWithRetry(/*here goes RetryContext but it's ignored in ServiceRequest*/null);
});
when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), eq(String.class)))
.thenReturn(myEntity);

//when:
ResponseEntity<String> response = serviceRequest.makeGetServiceCall(url);

//then:
assertEquals(myEntity, response);
}

我从方法调用 makeGetServiceCall 获得的响应对象始终返回 null。当我调试代码时,我在 resttemplate 上看到异常 org.mockito.exceptions.misusing.WrongTypeOfReturnValue: ResponseEntity cannot be returned by toString() toString() should return String 错误 mock 我返回 myEntity

我不确定我错过了什么。

最佳答案

嗯,你犯了很多错误......

  1. 我确定您想用 @Mock 注释 private RetryTemplate retryTemplate;,而不是 @InjectMocks
  2. @InjectMocks 应该转到 ServiceRequest serviceRequest;
  3. 您正在一些与 serviceRequest 无关的 mockRetryTemplatemockRestTemplate 上定义交互。相反,您应该使用带有 @Mock 注释的字段来定义交互,因为它们会被注入(inject)到您的测试对象中 (serviceRequest)
  4. 此外,您通常无法模拟 RestTemplate 并将其注入(inject)到 ServiceRequest 中,因为您一开始就没有为 RestTemplate< 使用依赖项注入(inject)ServiceRequest 中的/code>。您只需在 ServiceRequest.makeGetServiceCall
  5. 中实例化其实例即可
  6. 您在 Mockito.when(retryTemplate.execute(...) 行的错误方法上定义了交互。您的交互指定了 RetryTemplate.execute(RetryCallback, RecoveryCallback, RetryState) 而您的 ServiceRequest 使用另一种方法 RetryTemplate.execute(RetryCallback)
  7. 您还应该注意到 RetryTemplate.execute 是最终的,因此您无法在没有额外努力的情况下模拟它,如所述 here 。一般来说,您应该更喜欢接口(interface)而不是类,例如RestOperationsRetryOperations 分别优于 RestTemplateRetryTemplate,更加灵活。

也就是说,下面是解决您问题的工作测试。但请注意从 ServiceRequest 中删除 RestTemplate restTemplate = new RestTemplate(); 并将 restTemplate 设为一个字段,以便进行依赖注入(inject)。

@RunWith(MockitoJUnitRunner.class)
public class ServiceRequestTest {
@Mock
private RestTemplate restTemplate;

@Mock
public RequestConfig requestConfig;

@Mock
private RetryTemplate retryTemplate;

@InjectMocks
ServiceRequest serviceRequest;

@Test
public void makeGetServiceCall() throws Exception {
//given:
String url = "http://localhost:8080";
ResponseEntity<String> myEntity = new ResponseEntity<>(HttpStatus.ACCEPTED);
when(retryTemplate.execute(any(RetryCallback.class))).thenAnswer(invocation -> {
RetryCallback retry = invocation.getArgument(0);
return retry.doWithRetry(/*here goes RetryContext but it's ignored in ServiceRequest*/null);
});
when(restTemplate.exchange(eq(url), eq(HttpMethod.GET), any(HttpEntity.class), eq(String.class)))
.thenReturn(myEntity);

//when:
ResponseEntity<String> response = serviceRequest.makeGetServiceCall(url);

//then:
assertEquals(myEntity, response);
}
}

关于RestTemplate 和 RetryTemplate 的 JAVA Mockito 单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54915369/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com