在 Mockito 中很容易验证模拟对象上是否发生了特定交互(特定方法调用),并且verifyZeroInteractions()
可以检查是否根本没有发生交互。假设我正在测试一个接口,例如记录器的接口,使用诸如 、 等方法info()
。warn()
在error()
特定场景中,我知道应该调用其中一个方法,但我并不关心哪个方法。是否有一种紧凑的方法来检查是否发生了与模拟对象的任何交互,而无需指定应该调用哪个确切的方法?或者也许这种机制是不必要的,因为测试它的“Mockito 方式”与我想象的不同?
问问题
3112 次
3 回答
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");
虽然这不一定回答一般性问题(我认为您正在寻找的内容不存在),但它可以解决测试日志记录的特定问题。
于 2012-06-25T16:24:40.923 回答
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++;
}
}
于 2012-06-26T09:18:03.737 回答
1
如果要检查与模拟对象发生的任何交互,可以使用该Mockito.mockingDetails()
方法并检查调用次数是否不为零。当然,您也可以根据模拟细节做更详细的断言,但我想只检查非零就可以回答您的问题。
@ExtendWith(MockitoExtension.class)
public class TestClass {
@Mock
private Logger logger;
@InjectMocks
private Service service;
@Test
public void testMethod_shouldLogMultipleTimes() {
service.testMethod();
assertThat(Mockito.mockingDetails(logger).getInvocations().size()).isNotZero();
}
}
该代码示例用于assertj
检查调用次数是否不为零。
于 2021-10-13T15:25:14.167 回答