zoukankan      html  css  js  c++  java
  • grpc测试

    测试是软件开发中重要的一步,本文介绍如何创建grpc的测试来保证代码的质量。这里都沿用之前的server和client代码

    服务端测试

    public class HelloWorldServerTest {
      //定义服务名字用于绑定客户端调用的服务端
      private static final String UNIQUE_SERVER_NAME = "in-process server for " + HelloWorldServerTest.class;
      //创建一个进程内的server
      private final Server inProcessServer = InProcessServerBuilder.forName(UNIQUE_SERVER_NAME).addService(new HelloServiceImpl()).directExecutor().build();
      //创建一个进程内的channel
      private final ManagedChannel inProcessChannel = InProcessChannelBuilder.forName(UNIQUE_SERVER_NAME).directExecutor().build();
    
      /**
       * 初始化进城内服务器
       */
      @Before
      public void setUp() throws Exception {
        inProcessServer.start();
      }
    
      /**
       * 使用stub调用server并验证返回结果
       */
      @Test
      public void testSimple() throws Exception {
        HelloServiceGrpc.HelloServiceBlockingStub blockingStub = HelloServiceGrpc.newBlockingStub(inProcessChannel);
        String testName = "World";
        //调用服务
        blog.proto.ProtoObj.Result reply = blockingStub.simpleHello(ProtoObj.Person.newBuilder().setMyName(testName).build());
    	//验证·
        assertEquals("hello, " + testName, reply.getString());
      }
      
      /**
       * 关闭服务器和channel
       */
      @After
      public void tearDown() {
        inProcessChannel.shutdownNow();
        inProcessServer.shutdownNow();
      }
    }
    

    客户端测试

    在客户端测试之前,需要对之前的客户端进行一些改动,需要将channel变为实例变量,方便注入,这里以simple服务为例:

    public class HelloClient {
        private static final Logger logger = Logger.getLogger(HelloClient.class.getName());
    	//提出的channel
        private final ManagedChannel channel;
    	//stub
        private final HelloServiceGrpc.HelloServiceBlockingStub blockingStub;
    	//在构造方法中传入channel
        public HelloClient(ManagedChannel channel){
            this.channel=channel;
            blockingStub = HelloServiceGrpc.newBlockingStub(channel);
        }
    
        public void simple(String name) {
            logger.info("Will try to greet " + name + " ...");
            ProtoObj.Person person = ProtoObj.Person.newBuilder().setMyName(name).build();
            try {
                ProtoObj.Result response = blockingStub.simpleHello(person);
                logger.info(response.getString());
            } catch (StatusRuntimeException e) {
                logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
                return;
            }
        }
    }
    

    之后进行测试:

    public class HelloWorldClientTest {
      //spy一个服务实例
      private final HelloServiceGrpc.HelloServiceImplBase serviceImpl = spy(new HelloServiceGrpc.HelloServiceImplBase() {
      });
    
      private Server fakeServer;
      private HelloClient client;
      ManagedChannel channel;
      /**
       * 模拟server和channel并创建client
       */
      @Before
      public void setUp() throws Exception {
        String uniqueServerName = "fake server.java for " + getClass();
    	//创建进程内服务和channel
        fakeServer = InProcessServerBuilder.forName(uniqueServerName).directExecutor().addService(serviceImpl).build().start();
        InProcessChannelBuilder channelBuilder = InProcessChannelBuilder.forName(uniqueServerName).directExecutor();
        channel=channelBuilder.build();
    	//创建client
        client = new HelloClient(channel);
      }
    
      @Test
      public void greet_messageDeliveredToServer() {
        ArgumentCaptor< ProtoObj.Person> requestCaptor = ArgumentCaptor.forClass( ProtoObj.Person.class);
        String testName = "world";
    
        client.simple(testName);
    	//验证服务器期望收到的参数
        verify(serviceImpl).simpleHello(requestCaptor.capture(), Matchers.<StreamObserver<ProtoObj.Result>>any());
        assertEquals(testName, requestCaptor.getValue().getMyName());
      }
      
      @After
      public void tearDown() throws Exception {
    	//关闭channel和server
        channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
        fakeServer.shutdownNow();
      }
    }
    

    总结

    在单元测试时一大麻烦的是多线程的处理,使用InProcessServerBuilder会创建进程内的调用,server和client将同步在main线程中调用,这样就减少了多线程、异步测试会遇到的问题。

  • 相关阅读:
    ubuntu系统上常用的开发工具
    wamp环境下安装pear
    PHP中preg_match_all函数用法使用详解
    晚睡对策
    iphone相关
    090213 阴
    月曜日の予定(10:30までREVIEW  10:00まで完成予定)
    一个通知
    我还没走
    星期5
  • 原文地址:https://www.cnblogs.com/resentment/p/6914283.html
Copyright © 2011-2022 走看看