2012-05-31 5 views
24

Возможно ли перехватить все вызовы методов на макет в общем виде?Mockito - перехват любого вызова метода на макет

Пример

Учитывая поставщик при условии класса, таких как:

public class VendorObject { 

    public int someIntMethod() { 
     // ... 
    } 

    public String someStringMethod() { 
     // ... 
    } 

} 

Я хотел бы создать макет, который перенаправляет всех вызовов методы к другому классу, где есть метод сопоставления подписи:

public class RedirectedToObject { 

    public int someIntMethod() { 
     // Accepts re-direct 
    } 

} 

Когда(). thenAnswer() construc t в Mockito, похоже, соответствует счету, но я не могу найти способ сопоставить любой вызов метода с любыми аргументами. InvocationOnMock, безусловно, дает мне все эти детали в любом случае. Существует ли общий способ сделать это? Что-то, что будет выглядеть следующим образом, где, когда заменяется соответствующим кодом (VO *.):

VendorObject vo = mock(VendorObject.class); 
when(vo.anyMethod(anyArgs)).thenAnswer(
    new Answer() { 
     @Override 
     public Object answer(InvocationOnMock invocation) { 

      // 1. Check if method exists on RedirectToObject. 
      // 2a. If it does, call the method with the args and return the result. 
      // 2b. If it does not, throw an exception to fail the unit test. 

     } 
    } 
); 

Добавление обертки вокруг классов поставщиков, чтобы сделать насмехаясь легко не вариант, потому что:

  1. Слишком большая существующая база кода.
  2. Часть чрезвычайно важных приложений.
+0

Не говорите мне, что это так просто, как когда (vo) .thenAnswer (...): O – Karle

+0

«Часть чрезвычайно критически важных приложений». Как добавить объект mock/proxy, отличный от добавления оболочки в этом случае? Вы заинтересованы в том, чтобы делать это только для модульного тестирования или в самом приложении? –

+0

@mattb: Аспект производительности не является самым большим аргументом против использования классов-оболочек. Мы создали бы интерфейс, основанный на исходном объекте поставщика, и класс реализации, который пересылает запросы фактическому объекту поставщика. Время выполнения для этого будет небольшим по сравнению с фактическим объектом-продавцом, выполняющим его работу. Более важным аргументом является существующая база кода, использующая объекты поставщика напрямую. – Karle

ответ

39

Я думаю, что вы хотите:

VendorObject vo = mock(VendorObject.class, new Answer() { 
    @Override 
    public Object answer(InvocationOnMock invocation) { 

     // 1. Check if method exists on RedirectToObject. 
     // 2a. If it does, call the method with the args and return the 
     // result. 
     // 2b. If it does not, throw an exception to fail the unit test. 

    } 
}); 

Конечно, если вы хотите использовать этот подход часто, нет необходимости для ответа не быть анонимными.

От documentation: «Это довольно продвинутая функция, и, как правило, вам не нужно писать достойные тесты, однако это может быть полезно при работе с устаревшими системами». Похоже на тебя.

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