2016-12-07 11 views
4
public static ResponseBean call(Bean bean) throws Exception { 
    // statements... 
    IgnoreCall.ignoreMethodCall(bean); 
    // statements... 

    // return 
} 

С фрагмента кода выше, можно протестировать метод пренебрегая вызов IgnoreCall.ignoreMethod(Bean) без необходимости размещать все заявление под логическое условие?Игнорирование вызова внутреннего статического вызова

Вот блок тестовый фрагмент кода:

@RunWith(PowerMockRunner.class) 
@PrepareTest 
public ClassHelperTest { 

    @Test 
    public void testCall() throws Excpetion { 
     // stubbing... 
     ResponseBean responseBean = ClassHelper.call(bean); 
     // verify/ies 
     // assert/s 
    } 

} 

Примечания:

  • Рефакторинг ClassHelper.call(Bean) следует избегать. Даже при плохом дизайне OO рефакторинг является дорогостоящим.
  • Подпись метода блокируется, если для замены не применяется другой шаблон.
  • Пробовал с использованием Mockito.when и PowerMockito.when на целевом статическом методе, при выполнении отладки не выполнялось прерывание.
+2

Вещь: ** статическая ** - ненормальность в дизайне OO; и как вы только что заметили: это делает ваш код намного сложнее ** для тестирования. PowerMock может «исправить» эту проблему; но я бы рекомендовал вам изменить ваш производственный код. Нет статических вызовов, нет таких проблем. – GhostCat

+0

Если бы рефакторинг был прост, я бы сделал это к тому времени. К сожалению, с плохим дизайном OO под рукой я застрял в этом. Вы говорите о том, что «PowerMock может решить эту проблему», поделитесь тем, как это сделать? –

+0

Вы будете удивлены, как часто я получаю ответы, которые предлагают исправить сломанные проекты, а не использовать PowerMock. Во всяком случае, теперь вы получили ответ. – GhostCat

ответ

5

Как ваши комментарии показывают, что изменение вашего производственного кода невозможно, вам «просто» приходится погружаться в статические мошеннические аспекты PowerMock; как указано, например, here.

В основном вам необходимо включить IgnoreCall для статического насмешка; а затем вы делаете вызовы на ignoreMethodCall() a no-op.

Но вы продолжаете спрашивать: основная проблема с вопросом является то, что вы хотите, чтобы дразнить из метода статического, который недействительным. У меня есть полный пример ниже, но до этого некоторые объяснения.

Дело в том: вы вызываете метод по двум причинам:

  1. Это имеет побочный эффект
  2. Она возвращает значение, а может быть, вызывает побочный эффект, слишком

A void метод может только для побочных эффектов. И дело в том, что когда вы делаете статический насмешливый, тогда это работает на класс уровень.

Смысл: вы поручаете PowerMock «предотвращать» любой из статических методов какого-либо класса из исполнения; вы просто «стираете» побочные эффекты всех этих статических методов! Итак, сообщая PowerMock о том, что эти статические издевательства, все методы void уже «ушли».

Но, как сказано, вы также можете вызвать методы для их возвращаемого значения. И тогда, когда вы используете метод Mockito when(). Вы используете этот метод, чтобы сказать: когда вызывается этот метод возвращаемого значения, тогда сделайте то или это.

Короткий рассказ; вот [mcve], используя элементы, которые вы просили:

package ghostcat.test; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

class IgnoreCall { 
    public static void ignoreMethodCall(Object o) { 
    System.out.println("SHOULD NOT SHOW UP: " + o); 
    } 
} 

class CuT { 
    public static Object call(Object bean) { 
    System.out.println("statement1"); 
    IgnoreCall.ignoreMethodCall(bean); 
    System.out.println("statement2"); 
    return "whatever"; 
    } 
} 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(IgnoreCall.class) 
public class PMTest { 
    @Test 
    public void test() { 
    PowerMockito.mockStatic(IgnoreCall.class); 
    CuT.call("yeha"); 
    } 
} 

Как и в вашем примере ... есть IgnoreCall; используется в этом статическом методе, который я только что назвал «вызовом».

Это печатает:

statement1 
statement2 

Когда я иду и закомментируйте

//  PowerMockito.mockStatic(IgnoreCall.class); 

Он печатает:

statement1 
SHOULD NOT SHOW UP: yeha 
statement2 

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

Я работал с eclipse neon, IBM java8 JDK и просто импортировал все JAR из powermock-mockito-junit-1.6.6.zip в свой тестовый проект.

+0

Не могу понять, почему параметры прерывания не будут работать? Использовали 'Mockito.when' и' PowerMockito.when' и оба не работали соответственно. –

+0

Это должен быть принятый ответ. Вы прочитали ссылку @GhostCat? 'PowerMockito.mockStatic (IgnoreCall.class);' и убедитесь, что вы используете бегун PowerMocks. –

+0

@CyrilHorad Я согласен с тем, что говорит Дэвид. Понимаете, то, что вы намереваетесь сделать, * документировано * в ответе, на который я ссылаюсь. Какая часть вас не хватает? Вам действительно нужны люди, чтобы написать пример, особенно для вас. – GhostCat