2012-04-18 291 views
0

我有几个类别:StateProcessor国家。 我想写一个测试方法StateProcessor.process(State)。 这个方法的逻辑非常简单,但它包含了很多日志消息。单元测试和记录

logger.info(state.getSourse().toString()); 
if (state.getTarget() == Target.A) { 
logger.info(state.getCreationTime()); 
service.doSmth(state); 
} else { 
logger.info(state.getTagret().getName()); 
service.doOtherStff(state); 
} 

我不想真正国家实例传递给过程方法,因为这个类是非常复杂,它需要大量的代码来构建它的行。所以,我想传递Mockito创建的模拟对象。根据主要逻辑,我只需要模拟getTarget()方法。但执行将失败,NPE处于state.getTagret()。getName()state.getSourse()。toString()。但我不喜欢嘲笑所有这些方法的想法!他们只用于记录。另外,我不想每次添加日志消息时都修复测试。

日志记录在那里非常有用,所以我根本不想删除它。但嘲笑仅用于记录日志的方法看起来很奇怪。

我该如何解决这个问题?

+0

难道你不能配置测试环境来切断所有的'logger.info'消息,同时让你的dev显示它们吗? – 2012-04-18 15:34:18

+0

对不起,我没有明白你的意思。日志记录在当前时间被禁用。但我不能删除所有这些logger.info行 – NullPointer 2012-04-18 15:39:05

+0

我的意思是什么第一个回答状态 – 2012-04-18 16:00:23

回答

1

考虑嘲笑DEEP。这将导致每个方法调用返回一个模拟而不是null并阻止NPE。

Foo mock = mock(Foo.class, RETURNS_DEEP_STUBS); 
+0

这正是我需要的!工作正常!我正在寻找一些魔法,就是这样! – NullPointer 2012-04-18 16:24:57

0

您可以将所有的日志记录调用包含在if (!test) {}块中并注入测试属性。

或者您可以将它们放入if (logger.isInfoEnabled()) {}区块并配置禁用信息的日志记录,或者注入一个模拟记录器,该记录器返回isInfoEnabled()的假。

但日志记录是您的代码的关键部分。所以如果你真的想测试它不会在生产中爆炸,你应该测试生产代码中的空值,或者证明这些属性可能永远不会返回null,并且注入一个不返回null的模拟。 PS:你真的打算在代码中保留tagretsourse的属性吗?

+0

这是不错的想法包装日志与“如果”。但是这会弄乱代码。代码片段是捏造的,所以属性名称不是真实的。 – NullPointer 2012-04-18 16:28:22

1

你有什么是经典Law of Demeter侵犯,这是一个教科书案例嘲讽的问题。

作为一种替代方案,可以考虑将整个State对象记录在一个位置 - 比如在'if'块之前 - 并覆盖toString()方法以输出您需要查看的所有内容。那么你不需要对每个领域进行解引用,并模拟每种方法。