如何测试 java.net.http (Java 11) 请求 BodyPublisher?

How to test java.net.http (Java 11) requests BodyPublisher?

我正在尝试测试使用新 Java 11 java.net.http.HttpClient.

的代码

在我的生产代码中,我有这样的东西:

HttpClient httpClient = ... (gets injected)

HttpRequest request = HttpRequest.newBuilder().uri(URI.create("http://localhost:1234"))
        .POST(HttpRequest.BodyPublishers.ofByteArray("example".getBytes()))
        .build();

return httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray());

在我的测试中,我模拟了 HttpClient,因此得到了 java.net.http.HttpRequest。我如何get/test它的请求正文(=我的"example")?我可以调用 request.bodyPublisher() 来获得 HttpRequest.BodyPublisher,但我被卡住了。

如果您对 body 在处理程序中的外观感兴趣,您可以在 HttpRequest.BodyPublisher 订阅者的帮助下了解它。我们调用 subscription.request 以接收所有 body 项并收集它们。

我们的自定义订阅者:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Flow;

public class FlowSubscriber<T> implements Flow.Subscriber<T> {
    private final CountDownLatch latch = new CountDownLatch(1);
    private List<T> bodyItems = new ArrayList<>();

    public List<T> getBodyItems() {
        try {
            this.latch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return bodyItems;
    }

    @Override
    public void onSubscribe(Flow.Subscription subscription) {
        //Retrieve all parts
        subscription.request(Long.MAX_VALUE);
    }

    @Override
    public void onNext(T item) {
        this.bodyItems.add(item);
    }

    @Override
    public void onError(Throwable throwable) {
        this.latch.countDown();
    }

    @Override
    public void onComplete() {
        this.latch.countDown();
    }
}

测试中的用法:

@Test
public void test() {
    byte[] expected = "example".getBytes();

    HttpRequest.BodyPublisher bodyPublisher =
            HttpRequest.BodyPublishers.ofByteArray(expected);

    FlowSubscriber<ByteBuffer> flowSubscriber = new FlowSubscriber<>();
    bodyPublisher.subscribe(flowSubscriber);

    byte[] actual = flowSubscriber.getBodyItems().get(0).array();

    Assert.assertArrayEquals(expected, actual);
}