2012-06-25 9 views
5

Łatwo jest zweryfikować, że konkretna interakcja (określone wywołanie metody) wystąpiło na próbnym obiekcie w Mockito, i istnieje verifyZeroInteractions() dla sprawdzenia, że ​​żadne interakcje w ogóle nie wystąpiły. Załóżmy, że testuję interfejs taki jak rejestrator, z takimi metodami, jak info(), warn(), error() itd. W konkretnym scenariuszu wiem, że jedna z tych metod powinna zostać wywołana, ale tak naprawdę nie obchodzi mnie, który z nich. Czy istnieje zwarty sposób sprawdzenia, czy jakakolwiek interakcja z próbnym obiektem wystąpiła bez potrzeby określenia, która metoda powinna zostać wywołana? A może taki mechanizm nie jest konieczny, ponieważ "sposób Mockito" testowania tego byłby inny od tego, co sobie wyobrażam?Czy możliwe jest sprawdzenie arbitralnej interakcji za pomocą Mockito w zwarty sposób?

Odpowiedz

1

Jeśli możesz zlecić zewnętrznemu utworzeniu obiektu rejestratora z testowanej klasy, nie ma powodu, dla którego nie możesz napisać własnej implementacji testowej interfejsu dziennika, która będzie rejestrować, które metody zostały wykonane i wstrzyknąć je jako część twoja konfiguracja testu.

Próbne biblioteki robią wiele dobrego, ale czasami są takie przypadki, jak te, które można znaleźć tam, gdzie mogą nie pokrywać twoich potrzeb.

Jeśli piszesz własną implementację do testowania tak i wstrzyknąć go do yourt klasie testu badanego, to można stwierdzić na 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

To jest dokładnie tak, jak ja testuje moją klasę tak daleko, Zastanawiałem się tylko, czy Mockito nie może oszczędzić mi pisania trywialnych implementacji dla wszystkich metod. –

+0

Powiedziałbym, że robisz rozsądną rzecz Michała. Mockito nie obsługuje tego rodzaju testów. Twoim jedynym wyborem jest zejście z trasy 'ArgumentCaptor', o której wspomniał Kevin, ale to prowadzi do wielu" szumów "w twoich testowych klasach. – Brad

+0

Zgadzam się, że jest trochę hałaśliwy, ale większość szumu jest zlokalizowana na deklaracje i metodę Before, a nawet można dodać Captora do deklaracji poziomu klasy, jeśli ma być używana w wielu metodach testowych (nawet nie jest wymagana, jeśli nie ma dostępu do msg) . Zaletą korzystania z Mockito jest to, że masz już dostęp do pełnego API rejestrowania. Aby to zrobić w swoim przykładzie, musisz rozszerzyć możliwości ręcznie zwijanej makiety (przechwycić/pobrać dowolne # z zalogowanych wiadomości itp.). Jednak w przypadku prostych potrzeb Twój sposób wydaje się prostszy, czystszy, * i * możliwy do ponownego użycia, więc są one kilka plusów dla twojego podejścia. –

2

Z log4j, aby przetestować rejestrator robię następującą konfigurację:

@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); 
} 

a następnie w moim teście I wykonaj następujące czynności:

verifyZeroInteractions(log4jAppender); 

lub

verify(log4jAppender).doAppend(any(LoggingEvent.class); 

Jeśli musisz przetestować zarejestrowane wartości, możesz zamiast tego podać kontrolującego:

ArgumentCaptor<LoggingEvent> logCaptor = ArgumentCaptor.forClass(LoggingEvent.class); 
verify(log4jAppender).doAppend(logCaptor.capture()); 
assertTrue(logCaptor.getValue().contains("my text to match"); 

Chociaż nie musi to być odpowiedź na ogólne pytanie (nie sądzę, że to, czego szukasz), może rozwiązać ten konkretny problem podczas testowania rejestrowania.

Powiązane problemy