Reputation: 1076
I am using Netty 4.0 to create a distributed privacy preserving algorithm for my masters thesis. I do TDD and most of the time this works very well because of Netty's modular API. One problem I get stuck on last week is I do not know how to test code that depends on ChannelFutureListener
. So lets say I have following code in my application:
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;
}
Now I am trying to test this specific method with unit tests. For that to work, I need a way to mock out the ChannelFuture
(ChannelPromise) to control the call of operationComplete
method of the listener. I tried it with different approaches. Here is one example test case:
@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);
}
This test results in a NullPointerException
at DefaultPromise.notifyListeners()
. Therefore my question is, how could I test code that depends on ChannelFutureListener
s?
Upvotes: 1
Views: 1989
Reputation: 1076
I found out a way to solve my problem. It works if the mock of the channel (chMock
) is replaced with a real channel, for example EmbeddedChannel
. After that I use a spy
for the channel instead of the mock.
Here is my current solution:
@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: Thank you for your comment. It was a nice hint for my current solution.
Upvotes: 2