gpt4 book ai didi

java - 为什么 JMockIt 在这段代码中模拟 X 类的 getter X.getE() ?

转载 作者:太空宇宙 更新时间:2023-11-04 06:18:41 30 4
gpt4 key购买 nike

注意:问题末尾附有完整工作的代码片段

我有一个类的 JMockIt 测试 Service有两个依赖项(代码片段中的 FactoryConsumer)。该服务内部询问 FactoryX 的对象的依赖关系,然后将该对象传递给 Consumer该方法的依赖关系:

public void interact(int i, E e) {
X v = f.create(i, e);
c.consume(v);
}

在我的测试中,我想练习 Service.interact()方法并通过严格的期望假设消费者应收到满足特定属性的参数值。现在,由于类型 X 的参数是一个没有实现 equals() 的 POJO,我想使用它提供的 getter 方法来执行我的检查; X看起来像这样(完整的代码片段在问题末尾):

public static class X {
private final int i;
public final E e;
// ... see below for full snippet
public int getI() { return i; }
public E getE() { return e; } // E is an enum

所以我所做的就是尝试检查消费者是否收到 X.getI() == 2 的值和X.getE() == E.B我使用with(Delegate<X>)来做到这一点和withArgThat(Matcher<X>)在我的期望 block 中:

new StrictExpectations() {{
consumer.consume(withArgThat(new BaseMatcher() { // ...
// and
new StrictExpectations() {{
consumer.consume(with(new Delegate() { // ...

但是,这两项检查都失败了,因为当它们调用 X.getE() 时他们收到的东西不是枚举值 E.B 。单元测试的输出为:

-----------------------------------------RUNNING CHECKS ON: i=2, e=BDirect reference match.Reference through getter mismatch!Ordinal through getter reference: 0Identity hashcode from getter reference: 1282788025Identity hashcode of expected reference: 519569038-----------------------------------------RUNNING CHECKS ON: i=2, e=BDirect reference match.Reference through getter mismatch!Ordinal through getter reference: 0Identity hashcode from getter reference: 1911728085Identity hashcode of expected reference: 519569038

第一个问题是(这篇文章的标题):为什么 JMockIt 首先要干预这个 getter?据我所知,我没有要求它模拟类 X,因此对其 getter 方法的调用应该进入常规 X 字节码,但显然它没有;返回的枚举值的序数为零,这似乎是模拟的默认值。这是预期的行为,因为我错过/误解了某些东西,或者它可能是一个错误?

第二个问题是:假设 JMockIt 的行为有正当理由,我怎样才能实现我想要的并对只能通过 X 的 getter 方法获取的值执行这种检查?我如何修复此代码以告诉 JMockIt 只需离开类 X独自一人。

这是将编译和运行的完整代码片段(也在 http://pastebin.com/YRL7Pdzv ),我的类路径中有 junit-4.12、hamcrest-core-1.3 和 jmockit-1.14,并使用 Oracle JDK 1.7.0_51。

package demonstrate;import mockit.Delegate;import mockit.Mocked;import mockit.NonStrictExpectations;import mockit.StrictExpectations;import org.hamcrest.BaseMatcher;import org.hamcrest.Description;import org.junit.Before;import org.junit.Test;public class SomeTest {    @Mocked    Factory factory;    @Mocked    Consumer consumer;    @Before    public void setUp() {        new NonStrictExpectations() {{            factory.create(anyInt, (E) any);            result = new Delegate() {                @SuppressWarnings("unused")                public X create(int i, E e) {                    return new X(i, e);                }            };        }};    }    @Test    public void testWithMatcher() {        System.err.println("-----------------------------------------");        new StrictExpectations() {{            consumer.consume(withArgThat(new BaseMatcher() {                final int i = 2; final E e = E.B;                @Override                public boolean matches(Object item) {                    return runChecks((X) item, i, e);                }                @Override                public void describeTo(Description description) {                    description.appendText("\"i=" + i + ", e=" + e.name() + "\"");                }            }));        }};        new Service(factory, consumer).interact(2, E.B);    }    @Test    public void testWithDelegate() {        System.err.println("-----------------------------------------");        new StrictExpectations() {{            consumer.consume(with(new Delegate() {                @SuppressWarnings("unused")                public boolean check(X x) {                    return runChecks(x, 2, E.B);                }            }));        }};        new Service(factory, consumer).interact(2, E.B);    }    private static boolean runChecks(X actual, int i, E e) {        System.err.println("RUNNING CHECKS ON: " + actual);        if (actual.getI() != i) {            System.err.println("Primitive int mismatch!");            return false;        }        if (actual.e == e) {            System.err.println("Direct reference match.");        } else {            System.err.println("Reference mismatch!");            return false;        }        E otherE = actual.getE();        if (otherE != e) {            System.err.println("Reference through getter mismatch!");            System.err.println("Ordinal through getter reference: "                    + otherE.ordinal());            System.err.println("Identity hashcode from getter reference: "                    + System.identityHashCode(otherE));            System.err.println("Identity hashcode of expected reference: "                    + System.identityHashCode(e));            return false;        }        return true;    }    public enum E {        A, B    }    public static class X {        private final int i;        public final E e;        public X(int i, E e) {            this.i = i;            this.e = e;        }        @Override        public String toString() {            return "i=" + i + ", e=" + e.name();        }        public int getI() {            return i;        }        public E getE() {            return e;        }    }    public static class Factory {        public X create(int i, E e) {            return new X(i, e);        }    }    public static class Consumer {        public void consume(X arg) {        }    }    public static class Service {        private final Factory f;        private final Consumer c;        public Service(Factory f, Consumer c) {            super();            this.f = f;            this.c = c;        }        public void interact(int i, E e) {            X v = f.create(i, e);            c.consume(v);        }    }}

最佳答案

我在 jmockit-users 列表中被告知这实际上是一个错误。

建议的解决方法是使用 @Mocked(cascading = false) Factory 工厂; ,它确实使事情正常工作。

关于java - 为什么 JMockIt 在这段代码中模拟 X 类的 getter X.getE() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27731395/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com