EDIT: Это теперь подается как вопрос с Powermock здесь: http://code.google.com/p/powermock/issues/detail?id=449&thanks=449&ts=1371519268PowerMock StackOveflowError на ArrayListMultimap
я испытывал некоторый код, используя EasyMock, который вызывает метод, который возвращает ArrayListMultimap, и я не хочу идти к проблеме создания объекта коллекции, полного издевок, поэтому я решил просто издеваться над ArrayListMultimap и заставить его возвращать любые макеты, которые мне нужны в стандартном mock-объекте fasion. ArrayListMultimap оказывается окончательным, поэтому я выбросил на него пылевидную пыль PowerMock. Однако, когда я пробежал тест, который я получил:
java.lang.StackOverflowError
at java.lang.reflect.Method.copy(Method.java:143)
at java.lang.reflect.ReflectAccess.copyMethod(ReflectAccess.java:118)
at sun.reflect.ReflectionFactory.copyMethod(ReflectionFactory.java:282)
at java.lang.Class.copyMethods(Class.java:2757)
at java.lang.Class.getDeclaredMethods(Class.java:1793)
at org.easymock.internal.BridgeMethodResolver.getAllDeclaredMethods(BridgeMethodResolver.java:434)
at org.easymock.internal.BridgeMethodResolver.findBridgedMethod(BridgeMethodResolver.java:78)
at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:87)
at com.google.common.collect.ArrayListMultimap$$EnhancerByCGLIB$$2dd82dd1.equals(<generated>)
at org.easymock.internal.ExpectedInvocation.matches(ExpectedInvocation.java:85)
at org.easymock.internal.UnorderedBehavior.addActual(UnorderedBehavior.java:57)
at org.easymock.internal.MocksBehavior.addActual(MocksBehavior.java:87)
at org.easymock.internal.ReplayState.invokeInner(ReplayState.java:58)
at org.easymock.internal.ReplayState.invoke(ReplayState.java:46)
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:40)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:85)
at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:94)
at com.google.common.collect.ArrayListMultimap$$EnhancerByCGLIB$$2dd82dd1.equals(<generated>)
at org.easymock.internal.ExpectedInvocation.matches(ExpectedInvocation.java:85)
at org.easymock.internal.UnorderedBehavior.addActual(UnorderedBehavior.java:57)
at org.easymock.internal.MocksBehavior.addActual(MocksBehavior.java:87)
at org.easymock.internal.ReplayState.invokeInner(ReplayState.java:58)
at org.easymock.internal.ReplayState.invoke(ReplayState.java:46)
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:40)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:85)
at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:94)
at com.google.common.collect.ArrayListMultimap$$EnhancerByCGLIB$$2dd82dd1.equals(<generated>)
at org.easymock.internal.ExpectedInvocation.matches(ExpectedInvocation.java:85)
at org.easymock.internal.UnorderedBehavior.addActual(UnorderedBehavior.java:57)
at org.easymock.internal.MocksBehavior.addActual(MocksBehavior.java:87)
at org.easymock.internal.ReplayState.invokeInner(ReplayState.java:58)
at org.easymock.internal.ReplayState.invoke(ReplayState.java:46)
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:40)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:85)
at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:94)
at com.google.common.collect.ArrayListMultimap$$EnhancerByCGLIB$$2dd82dd1.equals(<generated>)
at org.easymock.internal.ExpectedInvocation.matches(ExpectedInvocation.java:85)
at org.easymock.internal.UnorderedBehavior.addActual(UnorderedBehavior.java:57)
at org.easymock.internal.MocksBehavior.addActual(MocksBehavior.java:87)
at org.easymock.internal.ReplayState.invokeInner(ReplayState.java:58)
at org.easymock.internal.ReplayState.invoke(ReplayState.java:46)
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:40)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:85)
at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:94)
at com.google.common.collect.ArrayListMultimap$$EnhancerByCGLIB$$2dd82dd1.equals(<generated>)
at org.easymock.internal.ExpectedInvocation.matches(ExpectedInvocation.java:85)
at org.easymock.internal.UnorderedBehavior.addActual(UnorderedBehavior.java:57)
В конце концов я дистиллированная проблему вниз к этому примеру:
import com.google.common.collect.ArrayListMultimap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.easymock.EasyMock.expect;
@RunWith(PowerMockRunner.class)
@PrepareForTest(ArrayListMultimap.class)
public class PurePowermockTest {
@Test
public void testPowerMockVsGuava() {
ArrayListMultimap map = PowerMock.createMock(ArrayListMultimap.class);
expect(map.put("foo", "bar")).andReturn(true);
PowerMock.replay(map);
map.put("foo", "bar"); // SOError!
}
}
Приведенный выше пример, конечно, ничего не испытываю, в map.put() вызов обычно будет внутри некоторого метода, который я тестирую. Этот код должен просто продемонстрировать проблему как можно более кратко. Я также знаю, что я могу просто создать ArrayListMultiMap и вернуть его, но отбросив это, насмехается над картой. Я почти уверен, что это ошибка в powermock, но мой вопрос таков:
Правильно ли я использую PowerMock? Должно ли это работать, или есть что-то, что я упустил о возможностях PowerMock или правильном использовании? Я использую метод EasyMock.expect, но я не вижу эквивалента в PowerMock, поэтому я предполагаю, что это нормально ...
Это хорошее подтверждение того, что это сила. Я зарегистрировал это как проблему здесь: http://code.google.com/p/powermock/issues/detail?id=449&thanks=449&ts=1371519268 – Gus