我目前正在为以下方法编写单元测试
@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。当我调试代码时,我在返回org.mockito.exceptions.misusing.WrongTypeOfReturnValue: ResponseEntity cannot be returned by toString() toString() should return String
的{{1}}模拟中看到异常resttemplate
错误,返回myEntity
我不确定我想念什么。
答案 0 :(得分:1)
好吧,你犯了很多错误...
private RetryTemplate retryTemplate;
而不是@Mock
来注释@InjectMocks
@InjectMocks
应该转到ServiceRequest serviceRequest;
mockRetryTemplate
无关的某些mockRestTemplate
和serviceRequest
上的交互。相反,您应使用带有@Mock
注释的字段来定义交互,因为它们已被注入到您的被测对象(serviceRequest
)中RestTemplate
并将其注入到ServiceRequest
中,因为您没有在RestTemplate
中首先为ServiceRequest
使用依赖项注入。您只需在ServiceRequest.makeGetServiceCall
Mockito.when(retryTemplate.execute(...
行中使用错误的方法定义了一个交互。您的互动指定了RetryTemplate.execute(RetryCallback, RecoveryCallback, RetryState)
,而您的ServiceRequest
使用了另一种方法RetryTemplate.execute(RetryCallback)
RetryTemplate.execute
是最终版本,因此如here所述,如果没有额外的努力就不能嘲笑它。通常,与类相比,您应该更喜欢使用接口,例如RestOperations
和RetryOperations
分别位于RestTemplate
和RetryTemplate
之上,以更加灵活。也就是说,下面是解决您的问题的工作测试。但是请注意,从RestTemplate restTemplate = new RestTemplate();
中删除ServiceRequest
并将restTemplate
设为一个字段,以便对其进行依赖注入。
@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);
}
}
答案 1 :(得分:1)
对于下面的我来说,它工作正常,否则,它总是返回null
when(retryTemplate.execute(any(),any(),any())).thenAnswer(invocation -> {
RetryCallback retry = invocation.getArgument(0);
return retry.doWithRetry(null);
});
,导入为
import static org.mockito.ArgumentMatchers.any;
答案 2 :(得分:0)
通用解决方案:
Mockito.when(retryTemplate.execute(Matchers.any(),Matchers.any(),Matchers.any())).thenAnswer(invocation -> {
RetryCallback retry = invocation.getArgumentAt(0,Matchers.any());
return retry.doWithRetry(null);
});