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

Java Mockito 1.9:格式化期望值(如自定义ArgumentMatcher中的“实际格式化程序”),java,formatting,mockito,powermock,matcher,Java,Formatting,Mockito,Powermock,Matcher,在Mockito 1.9.5中,我想在verifying方法的(按顺序)调用参数时格式化实际值 Mockito在ArcgumentMatchers中提供了一个可重写的describeTo方法,使我能够格式化期望值。 当使用PowerMockito的whenNew模拟诸如DatagramPacket之类的JRE类时,实际值的格式不是我喜欢的 在下面的示例中,我只对按顺序调用DatagramPacket的地址感兴趣。如果不是,我希望看到不匹配的实际值,而不是默认值toString()name“jav

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

Mockito在
ArcgumentMatcher
s中提供了一个可重写的
describeTo
方法,使我能够格式化期望值。 当使用PowerMockito的
whenNew
模拟诸如
DatagramPacket
之类的JRE类时,实际值的格式不是我喜欢的

在下面的示例中,我只对按顺序调用
DatagramPacket
的地址感兴趣。如果不是,我希望看到不匹配的实际值,而不是默认值
toString()
name“
java.net。DatagramPacket@7546a399

我的自定义匹配器只能匹配
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)
    ...
这就是我得到的:

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)
    ...
这就是我所期望的:

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()
实际值?

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

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());
        }
    }
}
静态类IsDatagramForAddress扩展ArgumentMatcher{
最终inetsocketaddr地址;
最后比较数据包;
公共IsDatagramForAddress(InetSocketAddress地址){
this.addr=addr;
}
公共布尔匹配(对象dgp){
if(数据包的dgp实例){
lastCompared=(DatagramPacket)dgp;
SocketAddress isa=lastCompared.getSocketAddress();
返回isa.equals(addr);
}
返回false;
}
@凌驾
公共无效说明(说明){
description.appendText(addr==null?null:addr.toString());
if(lastCompared!=null){
description.appendText(“上一个套接字地址是”+lastCompared.getSocketAddress());
}
}
}

有趣而实用的方法+1美元。但是你没有收到支票,因为我希望有一个现成的解决方案。这样做的缺点是,不熟悉此解决方案的开发人员可能会对输出和报告功能感到困惑(在本例中,这对我来说并不重要:)。因此,只有Mockito团队为您开发新功能时,您才会接受您问题的答案?