Mockito 1.9:格式化预期值(如自定义ArgumentMatcher中的“实际格式化程序”)

时间:2014-08-28 21:22:14

标签: java formatting mockito powermock matcher

在Mockito 1.9.5中,我希望在verify(按顺序)调用方法的参数时格式化实际值。

Mockito在describeTo中提供了一个可覆盖的ArcgumentMatcher<T>方法,使我能够格式化预期的值。 使用PowerMockito DatagramPacket模拟whenNew等JRE类时,实际值的格式不是我喜欢的格式。

在以下示例中,我只对按顺序调用DatagramPacket的地址感兴趣。如果没有,我希望看到不匹配的实际值,而不是默认的toString()名称&#34; java.net.DatagramPacket@7546a399&#34;。

我的自定义匹配器只能匹配InetSocketAddress

实施例

自定义匹配器:

static class IsDatagramForAddress extends ArgumentMatcher<DatagramPacket> {
    final InetSocketAddress addr;

    public IsDatagramForAddress(InetSocketAddress addr){
        this.addr = addr;
    }

    public boolean matches(Object dgp) {
        SocketAddress isa = ((DatagramPacket) dgp).getSocketAddress();
        boolean eq = isa.equals(addr);

        // System.out.println(dgp + ": " + isa + "< >" + addr + " == " + eq);

        return eq;
    }

    @Override
    public void describeTo(Description description) {
        description.appendText(addr == null ? null : addr.toString());
    }
}

测试:

private static DatagramPacket isDatagramForAddress(InetSocketAddress addr){
    return argThat(new IsDatagramForAddress(addr));
}

...

@Test
public void testSendIsCalledWithServersInOrder() throws Exception {

    InOrder order = inOrder(sock);

    order.verify(sock).send(isDatagramForAddress(new InetSocketAddress("8.8.8.2", 100)));
    order.verify(sock).send(isDatagramForAddress(new InetSocketAddress("8.8.8.1", 100)));
}

这就是我得到的:

org.mockito.exceptions.verification.VerificationInOrderFailure:
Verification in order failure
Wanted but not invoked:
datagramSocket.send(/8.8.8.1:100);
-> at xxxx.XxxxTest.testSendIsCalledWithServersInOrder(XxxxTest.java:95)
Wanted anywhere AFTER following interaction:
datagramSocket.send(
    java.net.DatagramPacket@7546a399
);
-> at xxxx.XxxxTest.testSendIsCalledWithServersInOrder(XxxxTest.java:90)

    at xxxx.XxxxTest.testSendIsCalledWithServersInOrder(XxxxTest.java:95)
    ...

这就是我的期望:

org.mockito.exceptions.verification.VerificationInOrderFailure:
Verification in order failure
Wanted but not invoked:
datagramSocket.send(/8.8.8.1:100);
-> at xxxx.XxxxTest.testSendIsCalledWithServersInOrder(XxxxTest.java:95)
Wanted anywhere AFTER following interaction:
datagramSocket.send(/8.8.8.2:100);
-> at xxxx.XxxxTest.testSendIsCalledWithServersInOrder(XxxxTest.java:90)

    at xxxx.XxxxTest.testSendIsCalledWithServersInOrder(XxxxTest.java:95)
    ...

问题归结为

如何格式化/ toString() 实际值?

1 个答案:

答案 0 :(得分:3)

您可以让ArgumentMatcher存储传递给它的最后一个对象,然后将其包含在describeTo方法中。这可能看起来像这样。

static class IsDatagramForAddress extends ArgumentMatcher<DatagramPacket> {
    final InetSocketAddress addr;
    DatagramPacket lastCompared;

    public IsDatagramForAddress(InetSocketAddress addr){
        this.addr = addr;
    }

    public boolean matches(Object dgp) {
        if (dgp instanceof DatagramPacket) {
            lastCompared = (DatagramPacket) dgp;
            SocketAddress isa = lastCompared.getSocketAddress();
            return isa.equals(addr);
        }

        return false;
    }

    @Override
    public void describeTo(Description description) {
        description.appendText(addr == null ? null : addr.toString());
        if (lastCompared != null) {
            description.appendText("Last socket address was " + lastCompared.getSocketAddress());
        }
    }
}