Какова стратегия для издевательства над статическими регистраторами в службе Java с использованием mockito

Я вижу, что над регистраторами издевались с помощью Powermock или какого-то переопределенного конструктора, который принимает logger.

Поскольку регистратор используется во всем коде, разве это не простой способ использовать только mockito? Какой-то способ игнорировать вызов или издеваться над ним - я не хочу проверять какое-либо сообщение, просто хочу избежать исключения Null Pointer

Я новичок в насмешливых фреймворках, поэтому мне интересно, а лучше использовать Jmockit вместо смешивания и сопоставления двух библиотек. Единственная причина, по которой пока следует избегать jomockit, - он слишком мощный и может быть легко использован неправильно!


person cpandey05    schedule 17.10.2013    source источник
comment
Зачем вам издеваться над регистраторами? Почему бы просто не позволить логированию произойти? Вы можете настроить тестовую конфигурацию для ведения журнала, которая предотвратит запись файла (например, просто отправить все журналы на консоль).   -  person John B    schedule 17.10.2013
comment
Хм, простая и лучшая идея.   -  person cpandey05    schedule 18.10.2013


Ответы (1)


Я использую проверку логов в тех случаях, когда считаю, что очень важно вести логи на определенном уровне. Вот как я это делаю с помощью Mockito:

Класс полезности

public final class LoggingTestUtil {

    private LoggingTestUtil() {
    }

    public static void setupLoggingMock(Logger logger, Appender<ILoggingEvent> appender) {
        logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
        when(appender.getName()).thenReturn("MOCK");
        logger.addAppender(appender);
    }

    public static void verifyLogAppended(Appender<ILoggingEvent> appender, final String loggedString) {
        verify(appender).doAppend(argThat(new ArgumentMatcher<LoggingEvent>() {
            @Override
            public boolean matches(final Object argument) {
                return ((LoggingEvent) argument).getMessage().contains(loggedString);
            }
        }));
    }

    public static void verifyLogAppendedAtLevel(Appender<ILoggingEvent> appender, final Level level) {
        verify(appender).doAppend(argThat(new ArgumentMatcher<LoggingEvent>() {
            @Override
            public boolean matches(final Object argument) {
                return ((LoggingEvent) argument).getLevel().equals(level);
            }
        }));
    }

    public static void verifyLogAppendedAtLevel(Appender<ILoggingEvent> appender, final Level level, final String loggedString) {
        verify(appender).doAppend(argThat(new ArgumentMatcher<LoggingEvent>() {
            @Override
            public boolean matches(final Object argument) {
                LoggingEvent event = (LoggingEvent) argument;
                return event.getLevel().equals(level) && event.getMessage().contains(loggedString);
            }
        }));
    }
}

В тестовом классе

private static Logger root;
@Mock
private static Appender<ILoggingEvent> mockAppender; // used to test that logging occurs

    @Test
    public final void testSomething(){
        LoggingTestUtil.setupLoggingMocks(root, mockAppender);
        underTest.doSomethingBad();
        LoggingTestUtil.verifyLogAppendedAtLevel(mockAppender, Level.ERROR, "bad thing");
    }
person Dennis    schedule 17.10.2013
comment
Я считаю, что насмешка — плохая стратегия для проверки журнала, поскольку она хрупкая и излишняя. Я создал правило JUnit, которое добавляет временное приложение к регистратору по умолчанию в log4j. Затем это позволяет проверить ведение журнала, просто добавив правило в тест. github.com/dancerjohn/LibEx/blob/master/testlibex/src/main/java/ - person John B; 17.10.2013
comment
@JohnB - Интересно... Проверю. Я нахожу это решение хрупким, поскольку оно ломается при изменении уровня/строки. Однако не будет ли правило в этом отношении точно таким же? Под излишеством вы имеете в виду, что макеты будут намного более тяжелыми? Я относительно новичок в насмешках, поэтому очень интересно узнать. :) - person Dennis; 17.10.2013
comment
1. Да, макеты гораздо более тяжелые, и ожидаемые вызовы методов должны быть настроены. 2. Тест не прошел бы ТОЛЬКО, если бы уровень ведения журнала был частью проверки. Если вы ожидаете сообщение об ОШИБКЕ, и это была ИНФОРМАЦИЯ, если произойдет сбой. Если вы ожидаете сообщение на любом уровне, то оно не подведет. - person John B; 17.10.2013