Mockito“thenThrow”在预期时不会抛出异常

问题描述 投票:1回答:1

我在尝试测试代表Rest Client的类时遇到问题。我在Spring Boot中使用RestTemplate。

这是抽象的RestClient类:

    public abstract class RestClient {
    ...

    public RestResponse sendPostRequest(URI baseUri, String resource, IRestRequest restRequest, ClassresponseClass)
            throws ServerException, ClientException {

        ...

        try {

            RestTemplate restTemplate = new RestTemplate();
            response = restTemplate.exchange(baseUri, HttpMethod.POST, getEntity(restRequest), responseClass);
            result = response.getBody();

            getLogger().debug("[{}] received", result);
            return result;
        } catch (HttpClientErrorException e) {
            throw new ClientException(e.getCause());
        } catch (HttpServerErrorException e) {
            throw new ServerException(e.getCause());
        } catch (Exception e) {
            getLogger().error("Error with cause: {}.", e.getMessage());
        }

        ...
    }
}

这是实际的实现:

    public class ActualRestClient extends RestClient {

    public RestResponse sendFetchFileRequest(URI baseUri, FetchFileRequest request) throws ServerException, ClientException {
        return sendPostRequest(baseUri, "FETCH_FILE", request, RestResponse.class);
    }
 }

这是测试:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ActualRestClient.class, RestClient.class})
public class ActualResRestClientTest {

private static final String REQUEST_URI = "something";

@InjectMocks
public ActualRestClient testee;

@Mock
private RestTemplate restTemplate;


@Test(expected = ServerException.class)
public void sendPostRequestWithResponseBody_throwsServerException() throws Exception {

    HttpServerErrorException httpServerErrorException = new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR);
    when(restTemplate.exchange(Mockito.any(URI.class), eq(HttpMethod.POST), Mockito.any(), eq(FetchFileRequest.class))).thenThrow(httpServerErrorException);

    testee.sendFetchFileRequest(new URI(REQUEST_URI), new FetchFileRequest());
 }
}

ClientException和ServerException是我通过扩展Exception类创建的异常。我的问题是,在RestClient类中,另一个异常被捕获(消息:“URI不是绝对的”)而不是HttpServerErrorException,我无法理解为什么。谢谢!

java unit-testing mockito powermock
1个回答
3
投票

正如评论者已经表达的那样:做new URI("something")已经向你投掷了。但即使您传递“有效”URI,您的代码也无法正常工作,因为您的结果存在误解。你看:

RestTemplate restTemplate = new RestTemplate();
response = restTemplate.exchange(baseUri, HttpMethod.POST, getEntity(restRequest), responseClass);

该代码存在于您所测试的类的方法中。但@InjectMocks仅适用于类的字段。

换句话说:当你的生产代码被执行时,会创建一个新的(完全不同的** ResponseTemplate实例。因此你的模拟规范是无关紧要的,因为这个方法首先不会在你的模拟上调用。

两种选择:

  • 将该局部变量转换为您所测试的类的字段(然后注入应该工作)
  • 或者,当您已经在使用PowerMock(ito)时,您可以使用该模拟框架来拦截对new()的调用。

我建议您使用选项一,并避免完全使用PowerMock(ito)扩展!

© www.soinside.com 2019 - 2024. All rights reserved.