gpt4 book ai didi

java - ArrayListMultimap 上的 PowerMock StackOveflowError

转载 作者:行者123 更新时间:2023-11-30 11:31:26 24 4
gpt4 key购买 nike

编辑: 现在,这已作为 Powermock 的一个问题在此处归档:http://code.google.com/p/powermock/issues/detail?id=449&thanks=449&ts=1371519268

我正在使用 EasyMock 测试一些代码,该代码调用一个返回 ArrayListMultimap 的方法,我不想麻烦地构建一个充满模拟的集合对象,所以我决定简单地模拟 ArrayListMultimap 并让它返回我在标准模拟对象时尚中想要的任何模拟。 ArrayListMultimap 结果是最终的,所以我在上面撒了一些 PowerMock Sprite 粉。然而,当我运行我的测试时,我得到了:

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 并将其返回,但撇开这一点,模拟 map 也应该有效。我很确定这是 powermock 中的错误,但我的问题是:

我是否正确使用 PowerMock?这应该有效,还是我错过了有关 PowerMock 的功能或正确使用的某些内容?我正在使用 EasyMock.expect 方法,但我没有在 PowerMock 上看到等效方法,所以我认为这没问题...

最佳答案

对我来说似乎是 PowerMock 中的一个错误(或用于字节码操作的 javassist)。因为我将 PowerMock 与 Mockito(即 PowerMockito)一起使用,所以我检查了它是否可以用 Mockito 重现 - 确实如此。给定测试:

@PrepareForTest(ArrayListMultimap.class)
public class PowerMockitoTest {

@Rule // used instead @RunWith(PowerMockRunner.class) in newer version of JUnit
public PowerMockRule rule = new PowerMockRule();

@Test
public void testPowerMockitoVsGuava() {
final ArrayListMultimap<String, String> mock =
PowerMockito.mock(ArrayListMultimap.class);
PowerMockito.when(mock.put("foo", "bar")).thenReturn(true);
Assert.assertTrue(mock.put("foo", "bar")); // SOError!
}

}

它仍然生成 SO 并指向代理 ArrayListMultimap 类中的 equals(堆栈跟踪中的 at com.google.common.collect.ArrayListMultimap$$EnhancerByCGLIB$$2dd82dd1.equals(<generated>))。

此特定错误可能与重复出现的 issue 88 有关- 当 equals 是 final 时(但在 ArrayListMultimap 中它不是......)或在其中使用 getClass()(它不是,另一方面使用 instanceof)或从 equals 调用另一个方法(它可能这里就是一个例子,因为 asMap() 在内部被调用 AbstractMultimap#equals )。另一方面,我检查了 LinkedListMultimap它与 PowerMock 一起工作得很好,所以它可能与 ArrayListMultimap 有关类型层次结构(扩展 AbstractMultimap -> AbstractMapBasedMultimap -> AbstractListMultimapLinkedListMultimap 不扩展)。

不幸的是,我不知道 PowerMock 的内部结构,也没有找到任何具体的东西,所以你应该联系 PowerMock 开发人员,可能是通过 Google Group .


回到你的问题——如果你能改变你的方法来返回ListMultimap ,那么你很好——你应该在接口(interface)上操作,而不是在具体实现上操作(你甚至不必使用 PowerMock)。 LinkedListMultimap也是这里的一个选项。

关于java - ArrayListMultimap 上的 PowerMock StackOveflowError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17151464/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com