首页 > 解决方案 > 如何在 JUnit 和 Mockito 中测试 2 条日志消息

问题描述

我对 JUnit 和 Mockito 很陌生。我正在尝试使用 JUnit 和 Mockito 编写一个测试用例来验证日志消息。我的代码中有 2 条日志消息。

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public int run(final String[] args) throws Exception {
    if (args.length != 2) {
      log.info("Usage: input-path output-path");
      log.info("Input and output path are required in the same sequence");
      System.exit(1);
    }
    final String inputPath = args[0];
    final String outputPath = args[1];
    //some code
    return 0;
}

我写的测试用例是

import org.apache.log4j.Appender;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.spi.LoggingEvent;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class testRun {

    @Mock
    private Appender mockAppender;

    @Before
    public void setup() {LogManager.getRootLogger().addAppender(mockAppender);}

    @After
    public void teardown() {LogManager.getRootLogger().removeAppender(mockAppender);}

    @Test
    public void testValidArguments() {
        //some code
 Logger.getLogger(TryTest.class).info("Usage: input-path output-path");
    Logger.getLogger(TryTest.class).info("Input and output path are required in the same sequence");
    ArgumentCaptor<LoggingEvent> argument = ArgumentCaptor.forClass(LoggingEvent.class);
    verify(appender,times(2)).doAppend(argument.capture());
    assertEquals(Level.INFO, argument.getValue().getLevel());
    assertEquals("Usage: input-path output-path", argument.getValue().getMessage());
    assertEquals("Input and output path are required in the same sequence", argument.getValue().getMessage());
     }
}

我已经看到了一些解决方案,但它们需要创建另一个我不想要的类。此外,当我执行代码时,它采用第二个值,即“输入和输出路径需要以相同的顺序”。如果只有一条日志消息,则代码可以正常执行。如果无法解决,我可以将两条消息放在一个 log.info 中。但是,我确实想知道这个特定问题是否有任何可能的解决方案。

标签: javaunit-testingjunitmockito

解决方案


如果您使用的是 sl4j 记录器,您可以使用ListAppender

@Test
void test() {
    Logger logger = (Logger) LogFactory.getLogger(YourClass.class);

    ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
    listAppender.start();
    logger.addAppender(listAppender);

    YourClass yourClass = new YourClass();
    yourClass.callYourMethodWithLogs();

    List<ILoggingEvent> logsList = listAppender.list;
    //make assertions with logList
}

推荐阅读