我正在尝试为此编写单元测试:
try (final DatagramChannel channel = helper.createChannel()) {
...
}
Run Code Online (Sandbox Code Playgroud)
在我的测试中,我模拟了帮助器(使用Mockito),并告诉helper.createChannel()返回一个模拟通道.
此测试失败了
java.lang.NullPointerException
at java.nio.channels.spi.AbstractInterruptibleChannel.close(AbstractInterruptibleChannel.java:111)
Run Code Online (Sandbox Code Playgroud)
我知道Java中的try-with-resources工具在退出try块时调用DatagramChannel中的close()方法,但是不应该调用模拟的DatagramChannel中的close()方法吗?
调试器告诉我AbstractInterruptibleChannel中的closeLock为null.
我应该继承DatagramChannel,重写其中的close()方法,然后模拟我的子类吗?或者,我是否以更深刻的方式做错了(帮助器模拟返回模拟)?
此致Fredrik Israelsson
测试代码,根据要求:
@Mock
private InetAddress peerAddress;
@Mock
private UDPChannelHelper helper;
@Mock
private DatagramChannel channel;
private UDPTransportImpl transport;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(helper.createChannel()).thenReturn(channel);
transport = new UDPTransportImpl(peerAddress, 0, helper);
}
@Test
public void testNormalSubmit() throws Exception {
transport.submit("Hello");
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我没有为channel.close()指定任何行为.我相信我不应该,因为close()返回void.
你正在嘲笑一个真正的阶级DatagramChannel,而且还在延伸AbstractInterruptibleChannel.然而,这AbstractInterruptibleChannel.close是最终的,Mockito目前无法模拟最终代码.这解释了为什么你的代码中有NPE.
我必须提醒你,人们普遍认为你不拥有的嘲弄类型是不好的做法.我已经看到人们这样做,多年后当真正的实现发生了变化时他们就有了不好的惊喜,但是模拟行为没有,所以当他们更新库的版本时,他们错误地认为一切都没问题.
仍然如果你想继续这种方式,因为你有正当理由(并且有一些),你可以返回一个接口的模拟,就像Channel实际扩展Closeable.或者您可以使用您需要与之交互的任何其他界面DatagramChannel.此外,如果您需要多个接口,请使用mock(Channel.class, withSetting().extraInterfaces(...)).
希望有助于干杯,布里斯
| 归档时间: |
|
| 查看次数: |
2120 次 |
| 最近记录: |