如何测试 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
,但我被卡住了。
- 我试图将其转换为
jdk.internal.net.http.RequestPublishers.ByteArrayPublisher
(实际上是),但它无法编译,因为相应的包未由模块导出。
- 我已经检查了
HttpRequest.BodyPublisher
接口(.contentLength()
、.subscribe(subscriber)
)中的可用方法,但我想它们不可能。
- 我试图创建一个新的
BodyPublisher
并使用 .equals()
比较它们,但是没有真正的实现,所以比较总是错误的。
如果您对 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);
}
我正在尝试测试使用新 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
,但我被卡住了。
- 我试图将其转换为
jdk.internal.net.http.RequestPublishers.ByteArrayPublisher
(实际上是),但它无法编译,因为相应的包未由模块导出。 - 我已经检查了
HttpRequest.BodyPublisher
接口(.contentLength()
、.subscribe(subscriber)
)中的可用方法,但我想它们不可能。 - 我试图创建一个新的
BodyPublisher
并使用.equals()
比较它们,但是没有真正的实现,所以比较总是错误的。
如果您对 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);
}