很容易验证Mockito中模拟对象上发生的特定交互(特定方法调用),并且verifyZeroInteractions()
用于检查根本没有发生交互。假设我正在使用诸如info()
,warn()
,error()
之类的方法测试诸如记录器之类的接口。在特定情况下,我知道应该调用其中一个方法,但我真的不在乎哪一个。是否有一种紧凑的方法来检查是否发生了与模拟对象的任何交互,而无需指定应该调用哪个确切的方法?或许也许这样的机制是不必要的,因为测试这种机制的“Mockito方式”会与我想象的不同?
答案 0 :(得分:2)
使用log4j来测试记录器,我进行以下设置:
@Mock private Appender log4jAppender;
private Logger logger;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
Logger root = Logger.getRootLogger();
if (!root.getAllAppenders().hasMoreElements()) {
// No appenders means log4j is not initialized!
BasicConfigurator.configure();
}
logger = Logger.getLogger(MyClassWhichLogs.class);
logger.addAppender(log4jAppender);
}
然后在我的测试中我执行以下操作:
verifyZeroInteractions(log4jAppender);
或
verify(log4jAppender).doAppend(any(LoggingEvent.class);
如果您需要测试记录的值,则可以改为使用捕获器:
ArgumentCaptor<LoggingEvent> logCaptor = ArgumentCaptor.forClass(LoggingEvent.class);
verify(log4jAppender).doAppend(logCaptor.capture());
assertTrue(logCaptor.getValue().contains("my text to match");
虽然这不一定能回答广义问题(我不认为你在寻找什么),但它可以解决测试记录的这个特定问题。
答案 1 :(得分:1)
如果您可以从被测试的类中外部化您的记录器对象的创建,那么您没有理由不编写自己的日志接口测试实现,该实现将记录已执行的方法并将其作为您的一部分注入测试设置。
模拟库有很多优点,但有时会出现像你发现的那些可能无法满足你需求的角落情况。
如果您编写自己的实现进行此类测试,并将其注入测试中的测试类,那么您可以在getCount() > 0
public class LoggerTestSupportImpl implements ILogger {
private int count = 0;
@Override
public int getCount() {
return count;
}
@Override
public void info(String message) {
count++;
}
@Override
public void warn(String message) {
count++;
}
}