我正在尝试为resttemplate.getForEntity()方法编写一个单元测试,并尝试覆盖Exception.class catch块。
下面是相同的代码:
import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.client.RestTemplate;
@Service
@Slf4j
public class ProductService {
private String productInfoBaseUrl = "http://localhost";
@Value("${service.product.metadata}")
private String productInfoPathProductMetadata;
private static final Logger logger = LoggerFactory.getLogger(ProductService.class);
@Autowired
RestTemplate restTemplate;
@Retryable(retryFor = {RuntimeException.class}, maxAttempts = 3, backoff = @Backoff(delay = 10000))
public ProductResponse getProductMetadata(String sku, HandlerResult handlerResult) {
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, "application/json");
String errorMsg;
String endpoint = getProductFetchMetadataEndpoint();
ResponseEntity<String> response;
try {
response = restTemplate.getForEntity(endpoint, String.class);
} catch (RuntimeException ex) {
errorMsg = "getProductMetadata threw exception: " + ex.getMessage();
HandlerResult.updateStatus(handlerResult, errorMsg, false);
throw ex;
}
catch (Exception ex) {
errorMsg = "getProductMetadata threw exception: " + ex.getMessage();
log.info(errorMsg);
HandlerResult.updateStatus(handlerResult, errorMsg, false);
return null;
}
ProductResponse metadataResponse;
Gson gson = new Gson();
try {
metadataResponse = gson.fromJson(response.getBody(), ProductResponse.class);
} catch (Exception e) {
errorMsg = String.format("Exception ProductResponse converting %s to map", response.getBody());
log.info(errorMsg);
HandlerResult.updateStatus(handlerResult, errorMsg, false);
return null;
}
return metadataResponse;
}
private String getProductFetchMetadataEndpoint() {
return productInfoBaseUrl + "/" + productInfoPathProductMetadata + "/";
}
}
字符串
以下是单元测试代码:
@ExtendWith(MockitoExtension.class)
public class ProductServiceTest {
@InjectMocks
ProductService productService;
//@Mock
@Spy
RestTemplate restTemplate;
@Test
public void testGetProductMetadataException() throws Exception {
Mockito.doThrow(RestClientException.class).when(restTemplate).getForEntity(any(), any());
ProductMetadataResponse result = productService.getProductMetadata("NX35100", null);
Assertions.assertNull(result);
}
}
型
我运行上面的单元测试得到下面的错误:
org.mockito.exceptions.base.MockitoException:
Checked exception is invalid for this method!
Invalid: java.lang.Exception
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:419)
型
有人能告诉我我错过了什么吗?
1条答案
按热度按时间cnjp1d6j1#
我认为这里有两个问题:
1.您应该使用
@Mock
而不是@Spy
,因为@Spy
只会监视实际的示例,并且在调用方法时仍然会触发实际的方法。在您的用例中,您希望在调用getForEntity
方法时抛出异常。1.你应该使用
when(xxx).thenThrow(yyy)
,而不是doThrow(yyy).when(xxx).getForEntity(...)
。后者是为void
返回类型设计的。并且getForEntity
不是void
方法。