5

在 Mockito 中很容易验证模拟对象上是否发生了特定交互(特定方法调用),并且verifyZeroInteractions()可以检查是否根本没有发生交互。假设我正在测试一个接口,例如记录器的接口,使用诸如 、 等方法info()warn()error()特定场景中,我知道应该调用其中一个方法,但我并不关心哪个方法。是否有一种紧凑的方法来检查是否发生了与模拟对象的任何交互,而无需指定应该调用哪个确切的方法?或者也许这种机制是不必要的,因为测试它的“Mockito 方式”与我想象的不同?

4

3 回答 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 回答