### Question:
RouteGuideService extends RouteGuideGrpc.RouteGuideImplBase { @Override public void listFeatures(Rectangle request, StreamObserver<Feature> responseObserver) { logger.info("ListFeatures"); int left = min(request.getLo().getLongitude(), request.getHi().getLongitude()); int right = max(request.getLo().getLongitude(), request.getHi().getLongitude()); int top = max(request.getLo().getLatitude(), request.getHi().getLatitude()); int bottom = min(request.getLo().getLatitude(), request.getHi().getLatitude()); for (Feature feature : features) { if (!RouteGuideUtil.exists(feature)) { continue; } int lat = feature.getLocation().getLatitude(); int lon = feature.getLocation().getLongitude(); if (lon >= left && lon <= right && lat >= bottom && lat <= top) { responseObserver.onNext(feature); } } responseObserver.onCompleted(); } @Inject  RouteGuideService(Features features); @Override void getFeature(Point request, StreamObserver<Feature> responseObserver); @Override void listFeatures(Rectangle request, StreamObserver<Feature> responseObserver); @Override StreamObserver<Point> recordRoute(final StreamObserver<RouteSummary> responseObserver); @Override StreamObserver<RouteNote> routeChat(final StreamObserver<RouteNote> responseObserver);  }### Answer:
@Test void listFeatures() throws Exception { Rectangle rect = Rectangle.newBuilder() .setLo(Point.newBuilder().setLongitude(0).setLatitude(0).build()) .setHi(Point.newBuilder().setLongitude(10).setLatitude(10).build()) .build(); Feature f1 = Feature.newBuilder() .setLocation(Point.newBuilder().setLongitude(-1).setLatitude(-1).build()) .setName("f1") .build(); Feature f2 = Feature.newBuilder() .setLocation(Point.newBuilder().setLongitude(2).setLatitude(2).build()) .setName("f2") .build(); Feature f3 = Feature.newBuilder() .setLocation(Point.newBuilder().setLongitude(3).setLatitude(3).build()) .setName("f3") .build(); Feature f4 = Feature.newBuilder() .setLocation(Point.newBuilder().setLongitude(4).setLatitude(4).build()) .build(); features.add(f1); features.add(f2); features.add(f3); features.add(f4); Collection<Feature> result = new HashSet<Feature>(); CountDownLatch latch = new CountDownLatch(1); StreamObserver<Feature> responseObserver = new StreamObserver<Feature>() { @Override public void onNext(Feature value) { result.add(value); } @Override public void onError(Throwable t) { fail(); } @Override public void onCompleted() { latch.countDown(); } }; asyncService.listFeatures(rect, responseObserver); assertTrue(latch.await(1, TimeUnit.SECONDS)); assertEquals(new HashSet<>(Arrays.asList(f2, f3)), result); }