How can I correctly make fun of an automatically closed resource?

I am trying to write unit test for this:

try (final DatagramChannel channel = helper.createChannel()) {

...

}

In my test, I mock the helper (using Mockito) and tell helper.createChannel () to return the mocked channel.

This test failed with

java.lang.NullPointerException
at java.nio.channels.spi.AbstractInterruptibleChannel.close(AbstractInterruptibleChannel.java:111)

I understand that the try-with-resources tool in Java calls the close () method in the DatagramChannel after exiting the try block, but should the close () method in the mocked DatagramChannel be called?

The debugger tells me that closeLock in AbstractInterruptibleChannel is null.

Should I subclass the DatagramChannel, override the close () method in it, and then mock my subclass? Or am I doing something wrong in a deeper way (helper layout returns layout)?

Regards, Fredrik Isalsonson

:

@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");
}

, channel.close(). , , close() void.

+5
3

DatagramChannel, AbstractInterruptibleChannel. AbstractInterruptibleChannel.close , Mockito . , NPE .

, , , , - . , , , , , , , .

, , ( ), , Channel, Closeable. , , DatagramChannel. , , mock(Channel.class, withSetting().extraInterfaces(...)).

, ,

+6

, , "" AbstractInterruptibleChannel ( FileChannel, DatagramChannel ..), closeLock, .

private static void fixChannelMock(AbstractInterruptibleChannel mockFileChannel) throws Exception {
    Field closeLockField = AbstractInterruptibleChannel.class.getDeclaredField("closeLock");
    closeLockField.setAccessible(true);
    closeLockField.set(mockFileChannel, new Object());
}

Java, , AbstractInterruptibleChannel .

+1

I had the same problem and using spy (..) instead of mock (..) worked for me. I tried to simulate an error while trimming the file, and if my system handled the error accordingly.

FileChannel fileChannel = spy(FileChannel.class);
mockStatic(FileChannel.class);
when(FileChannel.open(eq(filePath), eq(StandardOpenOption.WRITE))).thenReturn(fileChannel);
when(fileChannel.truncate(1000L)).thenThrow(new IOException("Unable to truncate file"));

...

// Snippet being tested!
fileChannel = FileChannel.open(filePath, StandardOpenOption.WRITE);
fileChannel.truncate(1000L); // Will throw the exception!
0
source

All Articles