JUnit - 不传播断言错误

时间:2012-11-02 11:06:38

标签: java junit jmock

我遇到JUnit / JMock中的某个错误。我试图模拟几个对象然后断言所有期望都满足。我正在运行一个简单的测试,例如:

@Test
public void sellingPutOptionProductDoesNotCauseDisclosure() throws PositionVerificationException, DataLoadException, MissingPriceException {
    final OptionProduct optionProduct = setupOptionProduct();
    context.assertIsSatisfied();
}

private OptionProduct setupOptionProduct() {
    final Option optionProduct = context.mock(Option.class);
    context.checking(new Expectations() {
        {
            oneOf(optionProduct).getUnderlyingProduct();
            will(returnValue(new Object()));
        }
    });
    return optionProduct;
}

Option是一个对象,我正在使用Mockery:

context = new Mockery() {
    {
        setImposteriser(ClassImposteriser.INSTANCE);
    }
};

如果我运行上面的测试,我感觉测试通过,其中JVM没有终止,最后一次在控制台打印出来:

线程“main”中的异常

任何可能导致这种情况的想法?

1 个答案:

答案 0 :(得分:0)

我参加派对有点晚了,但我遇到了类似的问题并且能够追查原因。 通常,当调用的方法不是期望的一部分时,JMock会构建日志,告诉您未找到的预期结果。在我的情况下,它尝试在遇到意外调用后创建该日志消息。创建日志消息的行为引发了一个异常,它使JMock感到困惑,它报告测试通过,当它实际失败时。

在我的例子中,抛出异常的原因是传递给“意外”函数调用的参数之一是类的实例。该类部分使用模拟对象进行初始化。当JMock尝试构建错误消息以告诉我有关意外调用时,它需要描述参数。通常它会说unexpected invocation: myobject.myMethod(param1,param2).

之类的东西

因为在我的例子中,param1包含作为模拟对象的成员变量,而param1类没有定义toString(),所以使用了默认的Object.toString()。

Object.toString()定义为:return getClass().getName() + "@" + Integer.toHexString(hashCode());

我对param1的哈希码的实现使用了一些这些模拟对象。那些对模拟对象进行计算哈希码的调用本身就是“意外”的调用,导致JMock在尝试向我描述测试失败时抛出异常。

不幸的是,JMock没有认识到这种情况并且仍然尽可能多地报告失败,而是似乎完全放弃了并且报告了测试,因为传递并且非常提及Exception in thread "main."

要查看是否发生了这种情况,我建议您检查有问题的函数调用中涉及的参数。如果它们中的任何一个是类,而不是接口,你应该看看他们对equals / hashcode / toString的使用是否使用了对成员变量的任何可疑调用,这些变量可能与你的场景被模拟的方式不一致。