Mocking java.net.DatagramSocket calls

456 views
Skip to first unread message

Brandon Gavino

unread,
Aug 22, 2012, 1:21:46 PM8/22/12
to powe...@googlegroups.com
Hello,

I've just started using PowerMock to assist in testing a simple
Android application (the non-Android specific classes), but have run
into a problem when trying to test a function that calls the
DatagramSocket.recieve() function.

Class under test:

/* imports */

public class NetOps extends Thread {

private DatagramSocket sock;
private Context svcContext;

private class InvalidMessageEx extends java.lang.Exception
{
private static final long serialVersionUID = 1L;
}

public NetOps(Context c)
{
try {
sock = new DatagramSocket(5700);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

svcContext = c;
}

@Override
public void run()
{
byte[] message = new byte[1024];
DatagramPacket pack = new DatagramPacket(message, message.length);

while(!interrupted())
{
/* Receive data on socket */
try {
sock.receive(pack);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

InetAddress addr = pack.getAddress();

/* Process the message */
try {
processMsg(pack.getData(), addr);
} catch (InvalidMessageEx e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

private void processMsg(byte[] message, InetAddress addr) throws
InvalidMessageEx
{
/* Stuff happens here */
}
}

~~~~~

Test Class:

/* Imports */

@PrepareForTest(NetOps.class)
@RunWith(PowerMockRunner.class)
public class NetOpsTest {


@Test
public void testRun() throws Exception{
byte[] message = {0x22};
InetAddress addr = InetAddress.getLocalHost();

NetOps mNetOps = PowerMock.createPartialMock(NetOps.class, "processMsg");
try {
PowerMock.expectPrivate(mNetOps, "processMsg", message,
addr).andThrow(new RuntimeException());
} catch (Exception e) {
e.printStackTrace();
}

DatagramSocket d = PowerMock.createMock(DatagramSocket.class);

byte[] b = new byte[1024];

DatagramPacket p = PowerMock.createNiceMock(DatagramPacket.class);

PowerMock.expectNew(DatagramPacket.class, b, b.length).andReturn(p);

Whitebox.setInternalState(mNetOps, "sock", d);

d.receive(p);

PowerMock.expectLastCall();

PowerMock.replayAll();

mNetOps.run();

PowerMock.verifyAll();
}
}

~~~~~

The issue I'm running into is that if I do not mock the DatagramPacket
constructor with expectNew, the DatagramPacket objects expected/actual
are not being matched, leading to a "Unexpected method call" :

java.lang.AssertionError:
Unexpected method call
DatagramSocket.receive(java.net.DatagramPacket@651dba45):
DatagramSocket.receive(java.net.DatagramPacket@6f9bb25a):expected 1, actual 0

When I try to use the expectNew line, the byte arrays do not seem to
match, and I am left with an "Unexpected constructor call
java.net.DatagramPacket()" listing the byte array contents. The
parameter values seem to match, so I'm not sure why the test is
generating this exception. If it's something basic I'm missing, please
let me know.

Thank you all in advance,
----------------------
Brandon Gavino

Johan Haleby

unread,
Aug 23, 2012, 1:37:19 AM8/23/12
to powe...@googlegroups.com
You may need to use argument matchers and this is not PowerMock specific. Goto this page and search for "Flexible Expectations with Argument Matchers".

/Johan


--
You received this message because you are subscribed to the Google Groups "PowerMock" group.
To post to this group, send email to powe...@googlegroups.com.
To unsubscribe from this group, send email to powermock+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/powermock?hl=en.


Reply all
Reply to author
Forward
0 new messages