Skip to content

Commit 7306df4

Browse files
authored
examples: unit test examples for users
Demonstrate unit testing gRPC clients and servers with `InProcessTransport`.
1 parent 7311572 commit 7306df4

18 files changed

+1469
-43
lines changed

examples/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,23 @@ $ mvn exec:java -Dexec.mainClass=io.grpc.examples.helloworld.HelloWorldServer
4444
$ # In another terminal run the client
4545
$ mvn exec:java -Dexec.mainClass=io.grpc.examples.helloworld.HelloWorldClient
4646
```
47+
48+
Unit test examples
49+
==============================================
50+
51+
Examples for unit testing gRPC clients and servers are located in [examples/src/test](src/test).
52+
53+
In general, we DO NOT allow overriding the client stub.
54+
We encourage users to leverage `InProcessTransport` as demonstrated in the examples to
55+
write unit tests. `InProcessTransport` is light-weight and runs the server
56+
and client in the same process without any socket/TCP connection.
57+
58+
For testing a gRPC client, create the client with a real stub
59+
using an
60+
[InProcessChannel](../core/src/main/java/io/grpc/inprocess/InProcessChannelBuilder.java),
61+
and test it against an
62+
[InProcessServer](../core/src/main/java/io/grpc/inprocess/InProcessServerBuilder.java)
63+
with a mock/fake service implementation.
64+
65+
For testing a gRPC server, create the server as an InProcessServer,
66+
and test it against a real client stub with an InProcessChannel.

examples/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ dependencies {
2828
compile "io.grpc:grpc-netty:${grpcVersion}"
2929
compile "io.grpc:grpc-protobuf:${grpcVersion}"
3030
compile "io.grpc:grpc-stub:${grpcVersion}"
31+
32+
testCompile "junit:junit:4.11"
33+
testCompile "org.mockito:mockito-core:1.9.5"
3134
}
3235

3336
protobuf {

examples/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@
2828
<artifactId>grpc-stub</artifactId>
2929
<version>${grpc.version}</version>
3030
</dependency>
31+
<dependency>
32+
<groupId>junit</groupId>
33+
<artifactId>junit</artifactId>
34+
<version>4.11</version>
35+
<scope>test</scope>
36+
</dependency>
37+
<dependency>
38+
<groupId>org.mockito</groupId>
39+
<artifactId>mockito-core</artifactId>
40+
<version>1.9.5</version>
41+
<scope>test</scope>
42+
</dependency>
3143
</dependencies>
3244
<build>
3345
<extensions>

examples/src/main/java/io/grpc/examples/advanced/HelloJsonServer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@
6161
public class HelloJsonServer {
6262
private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName());
6363

64-
/* The port on which the server should run */
65-
private int port = 50051;
6664
private Server server;
6765

6866
private void start() throws IOException {
67+
/* The port on which the server should run */
68+
int port = 50051;
6969
server = ServerBuilder.forPort(port)
7070
.addService(new GreeterImpl())
7171
.build()

examples/src/main/java/io/grpc/examples/errorhandling/DetailErrorSample.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,10 @@ public static void main(String[] args) throws Exception {
8686
new DetailErrorSample().run();
8787
}
8888

89-
private Server server;
9089
private ManagedChannel channel;
9190

9291
void run() throws Exception {
93-
server = ServerBuilder.forPort(0).addService(new GreeterGrpc.GreeterImplBase() {
92+
Server server = ServerBuilder.forPort(0).addService(new GreeterGrpc.GreeterImplBase() {
9493
@Override
9594
public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
9695
Metadata trailers = new Metadata();

examples/src/main/java/io/grpc/examples/errorhandling/ErrorHandlingClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ public static void main(String [] args) throws Exception {
6767
new ErrorHandlingClient().run();
6868
}
6969

70-
private Server server;
7170
private ManagedChannel channel;
7271

7372
void run() throws Exception {
74-
server = ServerBuilder.forPort(0).addService(new GreeterGrpc.GreeterImplBase() {
73+
// Port 0 means that the operating system will pick an available port to use.
74+
Server server = ServerBuilder.forPort(0).addService(new GreeterGrpc.GreeterImplBase() {
7575
@Override
7676
public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
7777
responseObserver.onError(Status.INTERNAL

examples/src/main/java/io/grpc/examples/header/HeaderClientInterceptor.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
package io.grpc.examples.header;
3333

34+
import com.google.common.annotations.VisibleForTesting;
35+
3436
import io.grpc.CallOptions;
3537
import io.grpc.Channel;
3638
import io.grpc.ClientCall;
@@ -49,7 +51,8 @@ public class HeaderClientInterceptor implements ClientInterceptor {
4951

5052
private static final Logger logger = Logger.getLogger(HeaderClientInterceptor.class.getName());
5153

52-
private static Metadata.Key<String> customHeadKey =
54+
@VisibleForTesting
55+
static final Metadata.Key<String> CUSTOM_HEADER_KEY =
5356
Metadata.Key.of("custom_client_header_key", Metadata.ASCII_STRING_MARSHALLER);
5457

5558
@Override
@@ -60,13 +63,13 @@ public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT
6063
@Override
6164
public void start(Listener<RespT> responseListener, Metadata headers) {
6265
/* put custom header */
63-
headers.put(customHeadKey, "customRequestValue");
66+
headers.put(CUSTOM_HEADER_KEY, "customRequestValue");
6467
super.start(new SimpleForwardingClientCallListener<RespT>(responseListener) {
6568
@Override
6669
public void onHeaders(Metadata headers) {
6770
/**
6871
* if you don't need receive header from server,
69-
* you can use {@link io.grpc.stub.MetadataUtils attachHeaders}
72+
* you can use {@link io.grpc.stub.MetadataUtils#attachHeaders}
7073
* directly to send header
7174
*/
7275
logger.info("header received from server:" + headers);

examples/src/main/java/io/grpc/examples/header/HeaderServerInterceptor.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
package io.grpc.examples.header;
3333

34+
import com.google.common.annotations.VisibleForTesting;
35+
3436
import io.grpc.ForwardingServerCall.SimpleForwardingServerCall;
3537
import io.grpc.Metadata;
3638
import io.grpc.ServerCall;
@@ -46,7 +48,8 @@ public class HeaderServerInterceptor implements ServerInterceptor {
4648

4749
private static final Logger logger = Logger.getLogger(HeaderServerInterceptor.class.getName());
4850

49-
private static Metadata.Key<String> customHeadKey =
51+
@VisibleForTesting
52+
static final Metadata.Key<String> CUSTOM_HEADER_KEY =
5053
Metadata.Key.of("custom_server_header_key", Metadata.ASCII_STRING_MARSHALLER);
5154

5255

@@ -59,7 +62,7 @@ public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
5962
return next.startCall(new SimpleForwardingServerCall<ReqT, RespT>(call) {
6063
@Override
6164
public void sendHeaders(Metadata responseHeaders) {
62-
responseHeaders.put(customHeadKey, "customRespondValue");
65+
responseHeaders.put(CUSTOM_HEADER_KEY, "customRespondValue");
6366
super.sendHeaders(responseHeaders);
6467
}
6568
}, requestHeaders);

examples/src/main/java/io/grpc/examples/helloworld/HelloWorldClient.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,15 @@ public class HelloWorldClient {
5050

5151
/** Construct client connecting to HelloWorld server at {@code host:port}. */
5252
public HelloWorldClient(String host, int port) {
53-
channel = ManagedChannelBuilder.forAddress(host, port)
53+
this(ManagedChannelBuilder.forAddress(host, port)
5454
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
5555
// needing certificates.
56-
.usePlaintext(true)
57-
.build();
56+
.usePlaintext(true));
57+
}
58+
59+
/** Construct client for accessing RouteGuide server using the existing channel. */
60+
HelloWorldClient(ManagedChannelBuilder<?> channelBuilder) {
61+
channel = channelBuilder.build();
5862
blockingStub = GreeterGrpc.newBlockingStub(channel);
5963
}
6064

examples/src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@
4444
public class HelloWorldServer {
4545
private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName());
4646

47-
/* The port on which the server should run */
48-
private int port = 50051;
4947
private Server server;
5048

5149
private void start() throws IOException {
50+
/* The port on which the server should run */
51+
int port = 50051;
5252
server = ServerBuilder.forPort(port)
5353
.addService(new GreeterImpl())
5454
.build()
@@ -89,7 +89,7 @@ public static void main(String[] args) throws IOException, InterruptedException
8989
server.blockUntilShutdown();
9090
}
9191

92-
private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
92+
static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
9393

9494
@Override
9595
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {

0 commit comments

Comments
 (0)