Mockito返回"java. lang.非法参数异常:URI不是绝对的"。我不知道为什么会发生这种情况,因为我似乎正确地模拟了restTemplate,而且因为我看到了这个异常,所以似乎restTemplate不是一个模拟。
这是我的班级
@Component
public class RestTemplateWrapper {
private static final Logger LOGGER = LoggerFactory.getLogger(RestTemplateWrapper.class);
public <T> ResponseEntity<T> callWebServiceGET(String url,HttpEntity<?> httpEntity,
ParameterizedTypeReference<T> parameterizedTypeReference) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<T> response=null;
LOGGER.trace("Entered callWebServiceGET");
LOGGER.info("Calling WebService {}", url);
try {
response=restTemplate.exchange(url, HttpMethod.GET, httpEntity, parameterizedTypeReference);
} catch (HttpClientErrorException e) {
if (HttpStatus.NOT_FOUND.equals(e.getStatusCode())) {
LOGGER.error("Service Unavailable - Code 404 returned. " + url + e.getMessage());
} else if (HttpStatus.UNAUTHORIZED.equals(e.getStatusCode())) {
LOGGER.error("Token Expired- Code 401 returned. " + e.getMessage());
} else if (HttpStatus.BAD_REQUEST.equals(e.getStatusCode())) {
LOGGER.error("Bad Input, 400 returned.{} {} ", url , e.getMessage(), e);
} else {
LOGGER.error("WEB Service Failure. " + e.getMessage());
}
}
return response;
}
}
下面是我的测试用例:
@PrepareForTest({RestTemplateWrapper.class})
public class RestTemplateWrapperTest {
@Mock
private RestTemplate mockRestTemplate;
@InjectMocks
private RestTemplateWrapper webUtils;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void callWebServiceGET_OK() {
HttpEntity<String> httpEntity= new ResponseEntity<>(HttpStatus.OK);
ResponseEntity<String> entityResponse=new ResponseEntity<>("MOCK_RESPONSE", HttpStatus.OK);
when(mockRestTemplate.exchange(eq("/objects/get-objectA"), eq(HttpMethod.GET), eq(httpEntity),any(
ParameterizedTypeReference.class))).thenReturn(
entityResponse);
ResponseEntity<String> mockResponse= webUtils.callWebServiceGET("",null, new ParameterizedTypeReference<String>(){
});
//verify(mockRestTemplate,times(1)).exchange(Matchers.anyString(), Matchers.any(), Matchers.any());
Assert.assertEquals("MOCK_RESPONSE",mockResponse.getBody());
}
}
答复:
URI is not absolute
java.lang.IllegalArgumentException: URI is not absolute
at java.net.URI.toURL(URI.java:1088)
at org.springframework.http.client.SimpleClientHttpRequestFactory.createRequest(SimpleClientHttpRequestFactory.java:145)
at org.springframework.http.client.support.HttpAccessor.createRequest(HttpAccessor.java:87)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:727)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:666)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:604)
at com.project.di.tp.purchaseorderservice.utils.RestTemplateWrapper.callWebServiceGET(RestTemplateWrapper.java:29)
at com.project.di.tp.purchaseorderservice.utils.RestTemplateWrapperTest.callWebServiceGET_OK(RestTemplateWrapperTest.java:51)
有什么办法解决这个问题吗?我已经试了4个小时了。
2条答案
按热度按时间wztqucjr1#
我找到了解决方法,问题似乎是我的类RestTemplateWrapper在callWebServiceGET内创建了一个示例,因此mockito不能模拟那个对象。如果在方法外设置对象,它可以工作,但我不想这样做。
有没有办法模仿一个方法中的对象?
qxsslcnc2#
尽管JavaDocs中没有明确说明,但您必须在其中提供一个绝对URL。
这是因为您没有提供相对URL相对于的基本URL。您也不能在浏览器中输入
"/objects/get-objectA"
作为URL。因此我建议您使用类似
"http://example.com/objects/get-objectA"
的内容来代替第一个参数:请注意,使用给定参数调用
webUtils.callWebServiceGET
不会使Mockito返回想要的答案,因此我将调用中的URL更改为您在Mockito.when
中期望的绝对URL,还更改了期望有类型化null
(类型化以匹配方法签名)的参数。更新:
正如您自己已经发现的那样,
Mockito.when
不起作用,因为您没有在tested方法中使用从测试中创建的mock,而是在callWebServiceGET
的每次调用中创建RestTemplate
的一个新示例(不知道为什么我之前没有看到它,抱歉!)我建议您使用构造函数将
RestTemplate
注入到测试类中:使用这段代码,Spring会自动将模拟的
RestTemplate
注入到测试中,但是要运行生产代码,您需要添加一个bean来提供用于注入的RestTemplate
。将其添加到Configuration类中,您还可以在其中定义其他Bean:
(在How to autowire RestTemplate using annotations的答案中找到此代码片段)
作为测试的一般建议:尽量避免在你想要测试的代码中使用
new
操作符,而使用注入来代替。如果你需要创建多个示例(例如在一个循环中),尝试注入一个为你创建示例的工厂-这样在测试中你就可以模拟工厂。