英文:
Spring RestTemplate.execute(), how to stub the response that gets passed in to my callback function?
问题
以下是代码部分的翻译:
public Dictionary getDictionary(int size, String text) {
return restTemplate.execute(url, HttpMethod.GET, null, response -> {
BufferedReader br = new BufferedReader(new InputStreamReader(response.getBody()));
List<String> words = new ArrayList<>();
String line;
while((line = br.readLine()) != null){
if (isMatch(line, size, text)){
words.add(line.toLowerCase());
}
}
br.close();
return new Dictionary(words);
});
}
private boolean isMatch(String word, int size, String text) {
if(word.length() != size) {
return false;
}
return wordUtil.isAnagram(word, text);
}
希望这有助于您理解代码。如果您有任何其他问题,请随时提出。
英文:
I have the following code. Dictionary is just a wrapper for a List of type String.
public Dictionary getDictionary(int size, String text) {
return restTemplate.execute(url, HttpMethod.GET, null, response -> {
BufferedReader br = new BufferedReader(new InputStreamReader(response.getBody()));
List<String> words = new ArrayList<>();
String line;
while((line = br.readLine()) != null){
if (isMatch(line, size, text)){
words.add(line.toLowerCase());
}
}
br.close();
return new Dictionary(words);
});
}
private boolean isMatch(String word, int size, String text) {
if(word.length() != size) {
return false;
}
return wordUtil.isAnagram(word, text);
}
I'm having a hard time test this method at the moment. The HTTP call just returns a list of words in plain text with new line separators.
I want to write a test where I can stub the response.getBody().
I.e. I want response.getBody() to return a bunch of words, and I'll assert that the returned Dictionary only contains the words that are of size size
and that are an anagram of the string text
.
Is this possible?
Thanks
答案1
得分: 1
可以存根(stub)一个接受回调的方法,并在调用存根时执行回调。
这个想法是:
- 使用
when
/thenAnswer
来在调用存根的方法时执行代码 - 使用传递给
thenAnswer
的invocationOnMock
来获取回调实例 - 调用回调,提供必要的参数
@Test
void testExecute() {
String responseBody = "line1\nline2";
InputStream responseBodyStream = new ByteArrayInputStream(responseBody.getBytes());
ClientHttpResponse httpResponse = new MockClientHttpResponse(responseBodyStream, 200);
when(restTemplate.execute(any(URI.class), eq(HttpMethod.GET), eq(null), any())).thenAnswer(
invocationOnMock -> {
ResponseExtractor<MyDictionary> responseExtractor = invocationOnMock.getArgument(3);
return responseExtractor.extractData(httpResponse);
}
);
MyDictionary ret = aController.getDictionary(1, "text");
// 对返回值进行断言以符合您的期望
}
话虽如此,这对于手头的任务来说似乎有点复杂。在我看来,如果您将处理 HTTP 的逻辑与业务逻辑分开,效果会更好。提取一个接受您的输入流的方法,并分开进行测试。
英文:
It is possible to stub a method taking a callback, and execute the callback when the stub is called.
The idea is to:
- use
when
/thenAnswer
to execute code when the stubbed method is called - use
invocationOnMock
passed tothenAnswer
to get the callback instance - call the callback, providing necessary params
@Test
void testExecute() {
String responseBody = "line1\nline2";
InputStream responseBodyStream = new ByteArrayInputStream(responseBody.getBytes());
ClientHttpResponse httpResponse = new MockClientHttpResponse(responseBodyStream, 200);
when(restTemplate.execute(any(URI.class), eq(HttpMethod.GET), eq(null), any())).thenAnswer(
invocationOnMock -> {
ResponseExtractor<MyDictionary> responseExtractor = invocationOnMock.getArgument(3);
return responseExtractor.extractData(httpResponse);
}
);
MyDictionary ret = aController.getDictionary(1, "text");
// assert ret against your expecations
}
Having said that, this seems to be a bit complicated for the task at hand. IMHO you will be better off if you separate the logic of dealing with Http from your business logic. Extract a method taking your inputStream, and test that separately.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论