GRPC有没有可以用来测试的Channel?

Does GRPC have a Channel that can be used for testing?

我想创建一个简单的测试,但在同一个 JVM 中使用 RPC。

我当时的想法是这样的

@Test
void foo() {
    Channel channel = new SomeMagicalObject(new MySystemImpl());
    SystemStub stub =  SystemGrpc.newStub(channel);

    var ret = stub.doSomething(...)
    assertThat(ret).isTrue();
}

我想知道是否已经构建了一些实现 Channel 的东西,它采用 GRPC 服务器实现。这样我就避免了 运行 Netty 和管理端口等。像这样...

private static Server server;
private static Channel channel;

@BeforeAll
@SneakyThrows
static void setupServer() {
    server = ServerBuilder.forPort(0)
            .addService(new MySystemImpl())
            .build()
            .start();
    channel = ManagedChannelBuilder.forAddress("localhost", server.getPort())
            .usePlaintext()
            .build();

}

@AfterAll
@SneakyThrows
static void teardownServer() {
    server
            .shutdown()
            .awaitTermination();
}

InProcess 传输正是您想要的。它是一种 full-fledged 传输,但使用方法调用和一些技巧来避免消息序列化。它非常适合测试,但也是 production-worthy。当与 directExecutor() 一起使用时,测试可以是确定性的。示例中使用了 InProcess 传输。一种用法见 HelloWorldServerTest

private static Server server;
private static Channel channel;

@BeforeAll
@SneakyThrows
static void setupServer() {
    // This code, except for the server.start(),
    // could be moved to the declarations above.
    server = InProcessServerBuilder.forName("test-name")
            .directExecutor()
            .addService(new MySystemImpl())
            .build()
            .start();
    channel = InProcessChannelBuilder.forName("test-name")
            .directExecutor()
            .build();
}

@AfterAll
@SneakyThrows
static void teardownServer() {
    server.shutdownNow();
    channel.shutdownNow();

    // Useful if you are worried about test
    // code continuing to run after the test is
    // considered complete. For a static usage,
    // probably not necessary.
    server.awaitTermination(1, SECONDS);
    channel.awaitTermination(1, SECONDS);
}