ClientProxyFactory { public static <T extends Entity & ServerMessageAware> T createEntityProxy(Class<T> clientType, Class<? super T> type, EntityClientEndpoint<ProxyEntityMessage, ProxyEntityResponse> entityClientEndpoint, Class<?>[] messageTypes, Codec codec) { return createProxy(clientType, type, entityClientEndpoint, messageTypes, codec); }  static T createEntityProxy(Class<T> clientType,
                                                                            Class<? super T> type,
                                                                            EntityClientEndpoint<ProxyEntityMessage, ProxyEntityResponse> entityClientEndpoint,
                                                                            Class<?>[] messageTypes,
                                                                            Codec codec); static T createProxy(Class<T> clientType,
                                  Class<? super T> type,
                                  EntityClientEndpoint<ProxyEntityMessage, ProxyEntityResponse> entityClientEndpoint,
                                  Class<?>[] messageTypes,
                                  Codec codec);  }
@Test public void testRegistersListeners() throws ExecutionException, InterruptedException, TimeoutException, EntityException, MessageCodecException { final SerializationCodec codec = new SerializationCodec(); final EntityClientEndpoint endpoint = mock(EntityClientEndpoint.class); final InvocationBuilder builder = mock(InvocationBuilder.class); when(endpoint.beginInvoke()).thenReturn(builder); when(builder.message(ArgumentMatchers.<EntityMessage>any())).thenReturn(builder); when(builder.withExecutor(ArgumentMatchers.<Executor>any())).thenReturn(builder); final InvokeFuture future = mock(InvokeFuture.class); when(builder.invoke()).thenReturn(future); when(future.get()).thenReturn(messageResponse(Integer.class, 42)); final ListenerAware proxy = ClientProxyFactory.createEntityProxy(ListenerAware.class, PassThrough.class, endpoint, new Class<?>[]{String.class, Integer.class, Long.class, Double.class}, codec); assertThat(proxy.sync(), is(42)); proxy.registerMessageListener(String.class, new StringMessageListener()); proxy.registerMessageListener(Integer.class, new MessageListener<Integer>() { @Override public void onMessage(final Integer message) { throw new UnsupportedOperationException("Implement me!"); } }); proxy.registerMessageListener(Long.class, new ComplexMessageListener()); proxy.registerMessageListener(Double.class, new MoreComplexMessageListener()); try { proxy.registerMessageListener(Object.class, new MessageListener() { @Override public void onMessage(final Object message) { throw new UnsupportedOperationException("Implement me!"); } }); fail(); } catch (IllegalArgumentException e) { } }