@Test
  public void testPubSub() throws InterruptedException, ExecutionException {
    final CountDownLatch done = new CountDownLatch(2);
    final Promise<Void> wassubscribed = new Promise<>();
    final AtomicReference<byte[]> gotmessage = new AtomicReference<>();
    final AtomicLong listeners = new AtomicLong(0);
    final AtomicBoolean failed = new AtomicBoolean();
    RedisClient.connect("localhost", 6379)
        .onSuccess(
            new Block<RedisClient>() {
              @Override
              public void apply(final RedisClient redisClient) {
                redisClient.addListener(
                    new ReplyListener() {
                      @Override
                      public void subscribed(byte[] name, int channels) {
                        wassubscribed.set(null);
                      }

                      @Override
                      public void psubscribed(byte[] name, int channels) {
                        failed.set(true);
                      }

                      @Override
                      public void unsubscribed(byte[] name, int channels) {
                        failed.set(true);
                      }

                      @Override
                      public void punsubscribed(byte[] name, int channels) {
                        failed.set(true);
                      }

                      @Override
                      public void message(byte[] channel, byte[] message) {
                        gotmessage.set(message);
                        redisClient.close();
                        done.countDown();
                      }

                      @Override
                      public void pmessage(byte[] pattern, byte[] channel, byte[] message) {
                        failed.set(true);
                      }
                    });
                redisClient
                    .subscribe("test")
                    .onSuccess(
                        new Block<Void>() {
                          @Override
                          public void apply(Void aVoid) {
                            RedisClient.connect("localhost", 6379)
                                .onSuccess(
                                    new Block<RedisClient>() {
                                      @Override
                                      public void apply(final RedisClient redisClient) {
                                        wassubscribed.onSuccess(
                                            new Block<Void>() {
                                              @Override
                                              public void apply(Void aVoid) {
                                                redisClient
                                                    .publish("test", "hello")
                                                    .onSuccess(
                                                        new Block<IntegerReply>() {
                                                          @Override
                                                          public void apply(
                                                              IntegerReply integerReply) {
                                                            listeners.set(integerReply.data());
                                                            redisClient.close();
                                                            done.countDown();
                                                          }
                                                        });
                                              }
                                            });
                                      }
                                    });
                          }
                        });
              }
            });
    done.await(10000, TimeUnit.MILLISECONDS);
    assertTrue(wassubscribed.get() == null);
    assertEquals("hello", new String(gotmessage.get()));
    assertEquals(1, listeners.get());
    assertFalse(failed.get());
  }