我想模拟属于我的一个类的RestTemplate示例变量的postForEntity方法,但它总是失败,并出现“URI不是绝对的”错误,尽管我在其他示例中看到anyString()作为URI传入。应该注意的是,我没有@Mock我的RestTemplate,因为我想测试它是否被它的父类的构造函数正确地构建(即超时)。
我不能发布实际的代码,但我正在测试的类看起来像这样:
public class MyClient {
...
@Getter
@Setter
private RestTemplate restTemplate = new RestTemplate();
public MyClient(Property x, Property y, Property z){
this.x = x;
this.y = y;
this.z = z;
}
//New constructor that I want to test
public MyClient(Property x, Property y, Property z, int timeout){
this(x, y, z);
this.restTemplate =((SimpleClientHttpRequestFactory)getRestTemplate().getRequestFactory()).setReadTimeout(timeout);
}
public makeRequests() {
...
//myEndpoint, myRequest are assigned earlier in this fx, CustomResponse is a custom class
ResponseEntity resEntity = getRestTemplate().postForEntity(myEndpoint, myRequest, CustomResponse.class);
}
}
字符串
我想测试MyClient.restTemplate是否超时:
@RunWith(MockitoJUnitRunner.class)
public class MyClassTest extends TestCase{
...
@Test
public void test_new_constructor(){
MyClient myClient = new MyClient(x, y, z, 1000);
RestTemplate restTemplate = myClient.getRestTemplate();
Mockito.when(restTemplate.postForEntity(anyString(), any(), any(Class.class))).thenAnswer(new AnswersWithDelay(100000, new Returns(new ResponseEntity(CustomResponse, HttpStatus.OK)) ));
//Will eventually add a delay to trigger a timeout + code for checking the exception, but it doesn't make it past the above line
myClient.makeRequests();
}
}
型
它在Mockito.when(restTemplate.postForEntity(anyString(), any(), any(Class.class))).thenAnswer(new AnswersWithDelay(100000, new Returns(new ResponseEntity(CustomResponse, HttpStatus.OK)) ));
线上失败,使用java.lang.IllegalArgumentException: URI is not absolute
,为什么会这样?首先测试一个实际的RestTemplate是一个坏主意吗?我想在网络调用上使用Mockito.when
会使测试不依赖于对实际端点的请求,但事实并非如此?
1条答案
按热度按时间jyztefdp1#
如果你没有模拟过一个示例,你不能用它调用
when
。when
是为模拟对象或间谍保留的。行
Mockito.when(restTemplate.postForEntity(anyString(), any(), any(Class.class)))
调用了带有参数anyString(), any(), any(Class.class)
的真实的postForEntity
方法,它实际上就是"", null, null
:ArgumentMatchers#anyString
:字符串
#any
:型
空字符串
""
显然不是绝对URI。如果你想测试一个类,你不能模拟它;否则你只会测试模拟对象/模拟行为,而不是你的真实的类。
也就是说,我认为可以假设
RestTemplate
已经被框架作者彻底测试过了-为什么你想测试它是否正确检测/触发超时?这应该已经被RestTemplate
的测试所覆盖。但是,如果您想测试您的应用程序代码是否正确处理了
RestTemplate
的超时,那么无论如何都要创建RestTemplate
的模拟示例,将其设置为超时的行为,并验证您自己的代码是否正确处理了模板的超时。