grpc java_如何对grpc-java服务器实现函数进行单元测试?

本文展示了如何使用InProcessServer对grpc-java服务进行单元测试。通过创建InProcessServer实例,启动并停止服务,然后利用ManagedChannel和stub进行服务调用来验证功能。示例中测试了获取服务器版本和Java版本的RPC方法。
摘要由CSDN通过智能技术生成

使用上面Eric提到的InProcess传输,单元测试非常简单。下面是一个例子了一下代码更明确:

我们测试基于此protobuff定义一个服务:

syntax = "proto3";

option java_multiple_files = true;

option java_package = "servers.dummy";

option java_outer_classname = "DummyProto";

option objc_class_prefix = "DMYS";

package dummy;

import "general.proto";

// The dummy service definition.

service DummyService {

// # Misc

// Returns the server version

rpc getVersion (Empty) returns (ServerVersion) {}

// Returns the java version

rpc getJava (Empty) returns (JavaVersion) {}

}

// Transmission data types

(包括下面的文件上面:)

syntax = "proto3";

option java_multiple_files = true;

option java_package = "general";

option java_outer_classname = "General";

option objc_class_prefix = "G";

// Transmission data types

message Empty {} // Empty Request or Reply

message ServerVersion {

string version = 1;

}

message JavaVersion {

string version = 1;

}

的DummyService基于从Protoc编译器生成的Java是如下:

package servers.dummy;

import java.util.logging.Logger;

import general.Empty;

import general.JavaVersion;

import general.ServerVersion;

import io.grpc.stub.StreamObserver;

public class DummyService extends DummyServiceGrpc.DummyServiceImplBase {

private static final Logger logger = Logger.getLogger(DummyService.class.getName());

@Override

public void getVersion(Empty req, StreamObserver responseObserver) {

logger.info("Server Version-Request received...");

ServerVersion version = ServerVersion.newBuilder().setVersion("1.0.0").build();

responseObserver.onNext(version);

responseObserver.onCompleted();

}

@Override

public void getJava(Empty req, StreamObserver responseObserver) {

logger.info("Java Version Request received...");

JavaVersion version = JavaVersion.newBuilder().setVersion(Runtime.class.getPackage().getImplementationVersion() + " (" + Runtime.class.getPackage().getImplementationVendor() + ")").build();

responseObserver.onNext(version);

responseObserver.onCompleted();

}

}

现在我们建立一个运行我们的虚拟服务的InProcessServer(或任何你想要的其他服务进行测试):

package servers;

import io.grpc.Server;

import io.grpc.inprocess.InProcessServerBuilder;

import java.io.IOException;

import java.util.logging.Logger;

import servers.util.PortServer;

/**

* InProcessServer that manages startup/shutdown of a service within the same process as the client is running. Used for unit testing purposes.

* @author be

*/

public class InProcessServer {

private static final Logger logger = Logger.getLogger(PortServer.class.getName());

private Server server;

private Class clazz;

public InProcessServer(Class clazz){

this.clazz = clazz;

}

public void start() throws IOException, InstantiationException, IllegalAccessException {

server = InProcessServerBuilder.forName("test").directExecutor().addService(clazz.newInstance()).build().start();

logger.info("InProcessServer started.");

Runtime.getRuntime().addShutdownHook(new Thread() {

@Override

public void run() {

// Use stderr here since the logger may have been reset by its JVM shutdown hook.

System.err.println("*** shutting down gRPC server since JVM is shutting down");

InProcessServer.this.stop();

System.err.println("*** server shut down");

}

});

}

void stop() {

if (server != null) {

server.shutdown();

}

}

/**

* Await termination on the main thread since the grpc library uses daemon threads.

*/

public void blockUntilShutdown() throws InterruptedException {

if (server != null) {

server.awaitTermination();

}

}

}

现在,我们可以使用下面的单元测试测试服务:

package servers;

import static org.junit.Assert.*;

import general.ServerVersion;

import io.grpc.ManagedChannel;

import io.grpc.StatusRuntimeException;

import io.grpc.inprocess.InProcessChannelBuilder;

import java.io.IOException;

import java.util.concurrent.TimeUnit;

import java.util.logging.Level;

import java.util.logging.Logger;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

import servers.dummy.DummyService;

import servers.dummy.DummyServiceGrpc;

import servers.dummy.DummyServiceGrpc.DummyServiceBlockingStub;

import servers.dummy.DummyServiceGrpc.DummyServiceStub;

public class InProcessServerTest {

private static final Logger logger = Logger.getLogger(InProcessServerTest.class.getName());

private InProcessServer inprocessServer;

private ManagedChannel channel;

private DummyServiceBlockingStub blockingStub;

private DummyServiceStub asyncStub;

public InProcessServerTest() {

super();

}

@Test

public void testInProcessServer() throws InterruptedException{

try {

String version = getServerVersion();

assertTrue(version == "1.0.0");

} finally {

shutdown();

}

}

/** Ask for the server version */

public String getServerVersion() {

logger.info("Will try to get server version...");

ServerVersion response;

try {

response = blockingStub.getVersion(null);

} catch (StatusRuntimeException e) {

logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());

fail();

return "";

}

return response.getVersion();

}

@Before

public void beforeEachTest() throws InstantiationException, IllegalAccessException, IOException{

inprocessServer = new InProcessServer(DummyService.class);

inprocessServer.start();

channel = InProcessChannelBuilder.forName("test").directExecutor()

// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid

// needing certificates.

.usePlaintext(true).build();

blockingStub = DummyServiceGrpc.newBlockingStub(channel);

asyncStub = DummyServiceGrpc.newStub(channel);

}

@After

public void afterEachTest(){

channel.shutdownNow();

inprocessServer.stop();

}

public void shutdown() throws InterruptedException {

channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);

}

}

测试只做测试两种方法之一,因为它仅用于说明目的。另一种方法可以进行相应的测试。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值