2016-02-14 2 views
0

Мне нужно высмеять экземпляр RestRequest с Mockito таким образом, чтобы этот метод возвращался, например, 10.0.0.1.Можно ли издеваться над вложенным объектом, к которому обращается отражение?

private static String getAddress(RestChannel channel) { 
    String remoteHost = null; 

    try { 
     NettyHttpChannel obj = (NettyHttpChannel) channel; 
     Field f = obj.getClass().getDeclaredField("channel"); 
     f.setAccessible(true); 

     SocketChannel sc = (SocketChannel) f.get(obj); 
     InetSocketAddress remoteHostAddr = sc.getRemoteAddress(); 
     remoteHost = remoteHostAddr.getAddress().getHostAddress(); 
     // Make sure we recognize localhost even when IPV6 is involved 
     if (localhostRe.matcher(remoteHost).find()) { 
      remoteHost = LOCALHOST; 
     } 
    } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 
     e.printStackTrace(); 
     return null; 
    } 

    return remoteHost; 
} 

Является ли это что-то возможно на всех? Мне нужно было бы высмеивать хотя бы до вызова SocketChannel.getRemoteAddress(), где сокет-канал является частным полем, доступным при отражении.

ответ

1

Предполагая this ваш NettyHttpChannel и канал представляет собой поле для org.jboss.netty.channel.Channel

Вы можете использовать конструктор:

NettyHttpChannel(NettyHttpServerTransport transport, 
    org.jboss.netty.channel.Channel channel, NettyHttpRequest request) 

с издевались SocketChannel:

NettyHttpServerTransport nettyHttpServerTransport = Mockito.mock(NettyHttpServerTransport.class); 
NettyHttpRequest NettyHttpRequest = Mockito.mock(nettyHttpRequest.class); 
InetSocketAddress inetSocketAddress = Mockito.mock(InetSocketAddress.class); 
SocketChannel channel = Mockito.mock(SocketChannel.class); 
Mockito.when(channel.getRemoteAddress()).thenReturn(inetSocketAddress); 
NettyHttpChannel nettyHttpChannel = new NettyHttpChannel(nettyHttpServerTransport, channel, request); 
// ... 
// call getAddress(nettyHttpChannel) 
// ... 

Это должно работать

+0

есть несколько опечаток в вашем ответе, и 'NettyHttpChannel' конструктор изменился, но я в конечном итоге делает его работать ваш путь, потому что Mockito НЕ МОЖЕТ Мок' типы Field'. – sscarduzio

+0

Рад, что ты заработал. –

0

Оказывается, Mockito не поддерживает насмешливые типы, такие как Field, поэтому прямое издевательство над материалом отражения не сократит его (как я боялся). Итак, я закончил предложение @RC. Но с некоторыми изменениями:

NettyHttpServerTransport nettyHttpServerTransport = mock(NettyHttpServerTransport.class); 
NettyHttpRequest nettyHttpRequest = mock(NettyHttpRequest.class); 
InetSocketAddress inetSocketAddress = new InetSocketAddress(address, 80); 
SocketChannel channel = mock(SocketChannel.class); 
when(nettyHttpRequest.getChannel()).thenReturn(channel); 
when(channel.getRemoteAddress()).thenReturn(inetSocketAddress); 
NettyHttpChannel c = new NettyHttpChannel(nettyHttpServerTransport, nettyHttpRequest, null, true); 
Смежные вопросы