Согласно the PowerMock docs, я должен работать с PowerMockRule
вместо @RunWith(PowerMockRunner.class)
и получать те же результаты.Можно ли издеваться над статическим методом в конечном классе, используя PowerMockRule вместо PowerMockRunner?
Кажется, я нашел случай, когда это неверно.
Ниже пример работает нормально:
package com.test.powermockstatics;
import static org.junit.Assert.assertEquals;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
final class FinalClassWithStaticCall {
public static int getIntStatic() {
return 1;
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(FinalClassWithStaticCall.class)
public class TestStaticMockingWithoutPowerMockRunner {
@Test
public void testStaticCall() {
mockStatic(FinalClassWithStaticCall.class);
when(FinalClassWithStaticCall.getIntStatic()).thenReturn(2);
assertEquals(FinalClassWithStaticCall.getIntStatic(), 2);
}
}
Но при переключении на правило так:
package com.test.powermockstatics;
import static org.junit.Assert.assertEquals;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
import org.junit.Rule;
import org.junit.Test;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.agent.PowerMockAgent;
import org.powermock.modules.junit4.rule.PowerMockRule;
final class FinalClassWithStaticCall {
public static int getIntStatic() {
return 1;
}
}
@PrepareForTest(FinalClassWithStaticCall.class)
public class TestStaticMockingWithoutPowerMockRunner {
static {
PowerMockAgent.initializeIfNeeded();
}
@Rule
public PowerMockRule rule = new PowerMockRule();
@Test
public void testStaticCall() {
mockStatic(FinalClassWithStaticCall.class);
when(FinalClassWithStaticCall.getIntStatic()).thenReturn(2);
assertEquals(FinalClassWithStaticCall.getIntStatic(), 2);
}
}
я получаю следующее исключение:
java.lang.IllegalArgumentException : Не может подкласс класса конечного класса com.test.powermockstatics.FinalClassWithStaticCall по адресу org.mockito.cglib.proxy.Enhancer.generateClass (Enhancer.java:447) в org.mockito.cglib.core.DefaultGeneratorStrategy.generate (DefaultGeneratorStrategy.java:25) at org.mockito.cglib.core. AbstractClassGenerator.create (AbstractClassGenerator.java:217) at org.mockito.cglib.proxy.Enhancer.createHelper (Enhancer.java:378) at org.mockito.cglib.proxy.Enhancer.createClass (Enhancer.java:318) на org.mockito.internal.creation.jmock.ClassImposterizer.createProxyClass (ClassImposterizer.java:110) на org.mockito.internal.creation.jmock.ClassImposterizer.imposterise (ClassImposterizer.java:62) в орг .powermock.api.mockito.internal.moc kcreation.MockCreator.createMethodInvocationControl (MockCreator.java:111) на org.powermock.api.mockito.internal.mockcreation.MockCreator.mock (MockCreator.java:60) на org.powermock.api.mockito.PowerMockito. mockStatic (PowerMockito.java:70) на com.test.powermockstatics.TestStaticMockingWithoutPowerMockRunner.testStaticCall (TestStaticMockingWithoutPowerMockRunner.java:30) на sun.reflect.NativeMethodAccessorImpl.invoke0 (нативный метод) при sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) по адресу java.lang.reflect.Method.invoke (Met hod.java:606) в org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall (FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run (ReflectiveCallable.java:12) на org.junit.runners.model.FrameworkMethod.invokeExplosively (FrameworkMethod.java:44) на org.junit.internal.runners.statements.InvokeMethod.evaluate (InvokeMethod.java:17) в org.powermock .modules.junit4.rule.PowerMockStatement.evaluate (PowerMockRule.java:49) на org.junit.runners.ParentRunner.runLeaf (ParentRunner.java:271) в org.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java : 70) по адресуorg.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:50) в org.junit.runners.ParentRunner $ 3.run (ParentRunner.java:238) в org.junit.runners.ParentRunner $ 1.schedule (ParentRunner .java: 63) на org.junit.runners.ParentRunner.runChildren (ParentRunner.java:236) на org.junit.runners.ParentRunner.access $ 000 (ParentRunner.java:53) в org.junit.runners.ParentRunner $ 2.оценить (ParentRunner.java:229) в org.junit.runners.ParentRunner.run (ParentRunner.java:309) по адресу org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run (JUnit4TestReference.java:50) на org.eclipse.jdt.internal.junit.runner.TestExecution.run (TestExecution.java:38) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:467) на org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:683) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run (RemoteTestRunner.java:390) на org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main (RemoteTestRunner.java:197)
Я выполняю рекомендации от Документов:
положить powermock- модуль-junit4 властвуй агента перед тем JUnit в классам
кто-нибудь знает официальное слово, если это ошибка в PowerMock или желаемое поведение (то есть, вы просто не можете издеваться с static
методом на final
класс с использованием PowerMockRule
)?
EDIT:
Пожалуйста, смотрите уточняющие детали в the comments under Gábor Lipták's answer. Я делаю не хочу использовать статически загруженный Агент, так как появляется динамически загруженный Агент, который должен быть способен выполнить работу?
Я знаю, что начинающий агент статически будет работать. (К сожалению, это не вариант в моем проекте.) Значит, кто-нибудь знает, является ли сбой динамически загруженного агента ошибкой в PowerMock? Или известное ограничение; и почему?
Здесь нет Maven. –
Затем загрузите банку и введите команду: java .... -javaagent: pathtojar/powermock-module-javaagent-1.5.6.jar. Это все. –
Я согласен, мне нужен агент. Агенты могут быть добавлены динамически, если вы посмотрите на код в https://github.com/jayway/powermock/blob/master/modules/module-impl/agent/src/main/java/org/powermock/modules/agent /PowerMockAgent.java для метода initializeIfNeeded, вы увидите, что он динамически привязывает Агента к запущенному процессу JVM. Я, к сожалению, должен динамически загружать Агент и не могу добавить аргументы для статической загрузки агента при запуске JVM. Документы, однако, заставляют это звучать так (статическая загрузка агента) необходимо только для использования с Maven. –