Netty,如何模拟ChannelFuture / ChannelPromise?

时间:2014-10-29 08:56:30

标签: java netty

我正在使用Netty 4.0为我的硕士论文创建分布式隐私保护算法。我做TDD并且大部分时间由于 Netty 的模块化API而非常有效。我上周遇到的一个问题是我不知道如何测试依赖于ChannelFutureListener的代码。所以我要说我的应用程序中有以下代码:

public ChannelFuture close() {
    if(channel == null)
        throw new IllegalStateException("Channel is null.");

    ChannelFuture f = channel.close();
    f.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture chf) throws Exception {
            channel = null;
        }
    });

    return f;
}

现在我试图用单元测试来测试这个特定的方法。为了实现这一点,我需要一种方法来模拟ChannelFuture(ChannelPromise)来控制监听器的operationComplete方法的调用。我尝试了不同的方法。以下是一个示例测试用例:

@Test
public void testConnectAfterClose() {
    Channel chMock = mock(Channel.class);
    ChannelPromise promise = new DefaultChannelPromise(chMock);

    when(chMock.close()).thenReturn(promise);
    node.connect(address);
    node.close();
    promise.setSuccess();
    node.connect(address);
}

此测试会产生NullPointerException DefaultPromise.notifyListeners()。因此,我的问题是,我如何测试依赖ChannelFutureListener s?

的代码

1 个答案:

答案 0 :(得分:1)

我找到了解决问题的方法。如果频道的模拟(chMock)被替换为真实频道,例如EmbeddedChannel,则它可以正常工作。之后我使用spy作为频道而不是模拟。

这是我目前的解决方案:

@Test
public void testConnectAfterClose() {
    Channel helper = new EmbeddedChannel(mock(ChannelHandler.class));
    chMock = spy(helper);

    when(chMock.close()).thenReturn(promise);
    node.connect(address);
    node.close();
    promise.setSuccess();
    node.connect(address);
}

@Morfic:谢谢你的评论。这是我当前解决方案的一个很好的暗示。