Spring错误Junit throws错误exception is invalid for this method

mo49yndu  于 5个月前  发布在  Spring
关注(0)|答案(1)|浏览(63)

我正在尝试为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)


有人能告诉我我错过了什么吗?

cnjp1d6j

cnjp1d6j1#

我认为这里有两个问题:
1.您应该使用@Mock而不是@Spy,因为@Spy只会监视实际的示例,并且在调用方法时仍然会触发实际的方法。在您的用例中,您希望在调用getForEntity方法时抛出异常。
1.你应该使用when(xxx).thenThrow(yyy),而不是doThrow(yyy).when(xxx).getForEntity(...)。后者是为void返回类型设计的。并且getForEntity不是void方法。

相关问题