是否可以模拟反射访问的嵌套对象?

时间:2016-02-14 16:46:17

标签: java unit-testing reflection mockito

我需要使用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()之前我需要进行模拟,其中套接字通道是反射访问的私有字段。

2 个答案:

答案 0 :(得分:1)

假设NettyHttpChannelorg.jboss.netty.channel.Channel而频道是NettyHttpChannel(NettyHttpServerTransport transport, org.jboss.netty.channel.Channel channel, NettyHttpRequest request) 的字段

您可以使用构造函数:

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) 
// ...

使用模拟this

{{1}}

那应该有用

答案 1 :(得分: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);