2015-03-02 1 views
0

Итак, в основном, есть плохой код, который я не могу изменить, который нужно протестировать. Традиционно вы вводите свои издевательства, но с этим кодом я не могу этого сделать, потому что нет методов setter. Хуже того, функция, которую мне нужно протестировать, вызывает кучу статических заводских методов - я не могу просто использовать стратегию MockUp для замены реализации там, потому что экземпляр класса не вводится вообще.Возможно ли использовать API Deencapsulation от JMockit для реализации метода обмена?

В C/++ вы можете получить указатель на функцию и узнать ее тип по ее подписи. Если вы изменили указатель, то вы могли бы потенциально изменить способ создания стека компилятором, и вы могли бы передать функцию вокруг и все, что было в Jazz.

Есть ли способ использовать Deencapsulation API для замены реализации статического метода? Используя это, я мог бы написать свой собственный класс, спуститься с традиционных, но возвращать насмешливые объекты, чтобы все еще была достигнута инъекция зависимостей?

public class TestedClass { 
    public static void testedMethod() { 
     UnMockableType instanceVariable = 
      UnInjectableFactory.staticFactoryConstructor(); 
     instanceVariable.preventControlFlowInfluenceThroughMocking(); 
    } 
} 
+0

Класс «Deencapsulation» - это всего лишь куча методов утилиты на основе отражения; для «замены реализации статического метода» вы использовали бы насмешливые API (либо '@ Mocked', либо' MockUp'). Вопрос не очень ясен, но насмехаться над статическим методом не должно быть проблемой. –

+0

Ну, если вы не можете вводить насмешливый метод, чтобы вернуть насмешливый экземпляр из статического метода фабрики, то как сделать метод MockUp на основе макета даже помогите? –

+0

Я, вероятно, не совсем понял вопрос; не могли бы вы привести примерный код, показывающий, что именно вы пытаетесь достичь? В любом случае API-интерфейсы JMockit предоставляют всевозможные возможности для насмешек и зависимостей, поэтому это должно быть выполнимо. –

ответ

1

достаточно просто:

@Test 
public void exampleTestUsingAMockUp() 
{ 
    new MockUp<UnMockableType>() { 
     @Mock 
     void preventControlFlowInfluenceThroughMocking() {} 
    }; 

    TestedClass.testedMethod(); 
} 

Выше UnInjectableFactory поругаем не бывает, потому что не нужно (если это просто инициализирует/улавливание UnMockableType).

Это также можно сделать с помощью @Mocked и API ожиданий.

+0

Проблема с этим - экземпляр, который возвращает статическая фабрика, - это * не * вымышленный экземпляр; да, вы можете объявить его издевательством, и вы можете объявить его введенным. Но эти экземпляры просто локальны для тестового класса, который содержит определения тестов. Новый MockUp создает альтернативный тип, но определение этого типа preventControlFlowInfluenceThroughMocking не является тем, что выполняется, оно все равно должно быть оригиналом. –

+0

Предполагая, что 'UnMockableType' является классом, тогда применение' MockUp 'будет влиять на * все * его экземпляров, существующих и будущих (на время теста). Если это базовый тип (интерфейс или базовый класс), то лучше использовать '@ Capturing'. –

+0

Хорошо, я подожду и просто испытаю этот ответ, когда у меня появится шанс. Я принимаю ваше слово за это, потому что я привык к JMock, а не JMockIt, который имеет другую семантику для того, как выполняется инъекция зависимостей. –