Spring RestTemplate.execute(),如何存根(stub)传递给我的回调函数的响应?

huangapple go评论62阅读模式
英文:

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 -&gt; {
        BufferedReader br = new BufferedReader(new InputStreamReader(response.getBody()));
        List&lt;String&gt; words = new ArrayList&lt;&gt;();
        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 来在调用存根的方法时执行代码
  • 使用传递给 thenAnswerinvocationOnMock 来获取回调实例
  • 调用回调,提供必要的参数
@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 to thenAnswer to get the callback instance
  • call the callback, providing necessary params
@Test
void testExecute() {
    String responseBody = &quot;line1\nline2&quot;;
    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 -&gt; {
          ResponseExtractor&lt;MyDictionary&gt; responseExtractor = invocationOnMock.getArgument(3);
          return responseExtractor.extractData(httpResponse);
      }
    );
    MyDictionary ret = aController.getDictionary(1, &quot;text&quot;);
    // 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.

huangapple
  • 本文由 发表于 2023年2月8日 19:38:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/75385241.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定