我在代码中的某处更改了一些不应该导致任何奇怪的测试失败的方法,但 JMock 似乎不这么认为。
我将问题归结为最少量的垃圾,看起来像这样:
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.Test;
public class TestMocking {
@Test
public void test() {
Mockery mockery = new Mockery() {{
setImposteriser(ClassImposteriser.INSTANCE);
}};
final Owner owner = mockery.mock(Owner.class);
final RealThing thing = mockery.mock(RealThing.class, "thing");
mockery.checking(new Expectations() {{
oneOf(owner).getThing(); will(returnValue(thing));
oneOf(thing).method(); will(returnValue(Collections.emptyList()));
}});
owner.getThing().method();
mockery.assertIsSatisfied();
}
public static interface Owner {
BaseThing getThing();
}
public static interface BaseThing {
Collection<?> method();
}
public static interface RealThing extends BaseThing {
List<?> method();
}
}
(编辑:即使不再有类,这现在也使用 ClassImposteriser,因为我想证明您可以在没有该冒名顶替者的情况下运行完全相同的代码并且测试将通过。)
运行结果:
unexpected invocation: thing.method()
expectations:
expected once, already invoked 1 time: owner.getThing(); returns <thing>
expected once, never invoked: thing.method(); returns <[]>
what happened before this:
owner.getThing()
所以你去了,当预期的thing.method() 从未被调用时,“意外的”thing.method() 。我之前已经看到当多线程类针对模拟对象进行测试时会发生这种情况,但这次它全部发生在单个线程中。就像 JMock 以某种方式从第一个方法调用返回了一个不同的模拟对象,即使我没有模拟这样的对象。
如果我删除了返回更具体类型的重写方法,那么它就会消失,但我显然不能这样做。同样,如果我删除 ClassImposteriser 的使用,问题就会消失,但我在真实测试中模拟的对象之一是其他人的类。我想我可以尝试在一个测试中使用两个 Mockery 实例,但除此之外我没有想法。