2012-06-25 2 views
5

Легко проверить, что конкретное взаимодействие (конкретный вызов метода) произошло на макет-объекте в Mockito, и есть verifyZeroInteractions() для проверки того, что никаких взаимодействий не произошло вообще. Предположим, что я тестирую интерфейс, такой как журнал регистрации, с такими методами, как info(), warn(), error() и т. Д. В конкретном сценарии я знаю, что один из этих методов должен быть вызван, но мне все равно, какой из них. Есть ли компактный способ проверить, что любое взаимодействие с макетным объектом произошло без необходимости указания того, какой именно метод следует вызывать? Или, может быть, такой механизм не нужен, потому что «метод Mockito» тестирования будет отличаться от того, что я себе представляю?Возможно ли произвольное взаимодействие с использованием Mockito в компактном режиме?

ответ

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++;  
    } 
} 
+1

Это точно, как я проверял мой класс до сих пор, Мне просто интересно, может ли Мокито избавить меня от написания тривиальных реализаций для всех методов. –

+0

Я бы сказал, что вы делали разумную вещь Михал. Mockito не поддерживает такой тип тестирования. Ваш единственный выбор - спуститься по пути 'ArgumentCaptor', как упоминал Кевин, но это приводит к большому количеству« шума »в ваших тестовых классах. – Brad

+0

Согласен, что это немного шумно, но большинство шумов локализуется в объявлениях и методе Before, и вы даже можете добавлять объявления Captor в класс, если они должны использоваться в нескольких методах тестирования (даже если они не нужны, если не доступны для сообщений msgs) , Самое приятное в использовании Mockito - это то, что вы уже имеете доступ к полному API регистрации. Для этого в вашем примере вам нужно расширить возможности вашего ручного прокатки (захватить/получить произвольное количество зарегистрированных сообщений и т. Д.). Но для простых нужд ваш путь кажется более простым, более чистым, * и * многоразовым, так что это некоторые плюсы для вашего подхода. –

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"); 

Хотя это не обязательно отвечает на обобщенный вопрос (я не думаю, что вы ищете), он может решить эту конкретную проблему для тестирования ведения журнала.

Смежные вопросы