2012-08-30 89 views
7

我已经集成PowerMock和PowerRule在JUnit用的Mockito获得了Javassist在JUnit不PowerMock和PowerRule发现的Mockito

以下是相关性:

<dependency> 
     <groupId>javassist</groupId> 
     <artifactId>javassist</artifactId> 
     <version>3.12.0.GA</version> 
     </dependency> 
<dependency> 
     <groupId>asm</groupId> 
     <artifactId>asm</artifactId> 
     <version>3.3.1</version> 
</dependency> 

<dependency> 
     <groupId>cglib</groupId> 
     <artifactId>cglib</artifactId> 
     <version>2.2.2</version> 
</dependency> 
<dependency> 
     <groupId>org.powermoc</groupId> 
    <artifactId>powermock-module-junit4</artifactId> 
    <version>1.4.12</version> 
    <scope>test</scope> 
    </dependency> 
<dependency> 
    <groupId>org.powermock</groupId> 
    <artifactId>powermock-api-mockito</artifactId> 
    <version>1.4.12</version> 
    <scope>test</scope> 
</dependency> 
<dependency> 
     <groupId>org.powermock</groupId> 
     <artifactId>powermock-module-junit4-rule</artifactId> 
     <version>1.4.12</version> 
     <scope>test</scope> 
</dependency> 
<dependency> 
     <groupId>org.powermock</groupId> 
     <artifactId>powermock-classloading-objenesis</artifactId> 
     <version>1.4.12</version> 
     <scope>test</scope> 
</dependency> 

// My test class is: 

public class TestClass extends AbstractShiroTest{ 
    @Rule 
    public PowerMockRule rule = new PowerMockRule(); 
    @Autowired 
    SomeService someService; 
    @Before 

    public void setUp(){ 
    Map<String, Object> newMap = new HashMap<String, Object>(); 
    newMap.put("userTimeZone", "Asia/Calcutta"); 
    Subject subjectUnderTest = mock(Subject.class); 
      when(subjectUnderTest.getPrincipal()).thenReturn(LMPTestConstants.USER_NAME); 
    Session session = mock(Session.class); 
    when(session.getAttribute(LMPCoreConstants.USER_DETAILS_MAP)).thenReturn(newMap); 
    when(subjectUnderTest.getSession(false)).thenReturn(session); 
    setSubject(subjectUnderTest); 
    PowerMockito.mockStatic(CasSessionUtil.class); 
    when(CasSessionUtil.getCarrierId()).thenReturn(1L); 
} 

    @Test 

public void myTestMethod() { 
someService.doSomething(); 
} 
} 

其中DoSomething的是调用静态方法我需要嘲笑。 现在,当我运行我的测试情况下,我得到javassist.NotFoundException:$ Proxy88

完整堆栈跟踪:

了java.lang.RuntimeException:javassist.NotFoundException:$ Proxy88 在org.powermock .core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:187) 在org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:147) 在org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader .java:67) at java.lang.ClassLoader.loadClass(ClassL (Class Method) at java.lang.Class.forName(Class.java:247) ) at org.powermock.api.support.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:66) at org.powermock.api.support.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:26) at org.powermock.classloading.DeepCloner .cloneFields(DeepCloner.java:243) at org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128) at org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248) at org.powermock .classloading.DeepCloner.performClone(DeepCloner.java:128) at org.powermock.classloading.DeepCloner.clon eFields(DeepCloner.java:248) at org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128) at org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248) at org.powermock。 classClient.DeepCloner.performClone(DeepCloner.java:128) at org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248) at org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128) at org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248) at org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128) at org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java: 248) at org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128) at org.powermock.classloading.DeepCloner.clone(DeepCloner.java:82) at org.powermock.classloading.DeepCloner.clone(DeepCloner.java:69) at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor。 java:89) at org.springframework。org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78) at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:49) at org.springframework。 test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) at org.junit.runners.BlockJUnit4ClassRunner。 runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runn ers.ParentRunner $ 3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners。ParentRunner.access $ 000(ParentRunner.java:42) at org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:184) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks。 java:61) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 在org.junit.runners.ParentRunner.run(ParentRunner.java:236) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 在org.eclipse.jdt.internal。 junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal。 junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit。 runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner。 RemoteTestRunner.main(RemoteTestRunner.java:197) 产生的原因:javassist.NotFoundException:$ Proxy88 在javassist.ClassPool.get(ClassPool.java:436) 在org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader。 java:180) ... 46更多

如果我改变的关系是不以

<dependency> 
      <groupId>org.powermock</groupId> 
      <artifactId>powermock-classloading-xstream</artifactId> 
      <version>1.4.12</version> 
      <scope>test</scope> 
     </dependency> 

然后我得到一个不同的充例外。请参阅 - https://stackoverflow.com/questions/12176049/suggest-work-around-for-com-thoughtworks-xstream-converters-conversionexception

我甚至用Javassist版本15,但得到同样的问题

请帮助试过..

回答

7

找到了解决办法自己:

使用下面的依赖关系(电力模拟和功率规则)仅

<!-- Required for PowerMock --> 
    <dependency> 
     <groupId>org.powermock</groupId> 
     <artifactId>powermock-api-mockito</artifactId> 
     <version>1.4.12</version> 
     <scope>test</scope> 
    </dependency> 
    <!-- Required for PowerMockRule --> 
    <dependency> 
     <groupId>org.powermock</groupId> 
     <artifactId>powermock-module-junit4-rule-agent</artifactId> 
     <version>1.4.12</version> 
     <scope>test</scope> 
    </dependency> 

现在我没有得到任何上述异常

+0

我有同样的问题,添加上述依赖项解决了问题。但是我面临着另一个问题,即代码没有达到调试中断点。 – aamir

+0

谢谢,真的帮了我很多:) –

+0

不要忘记upvote :) – Bhuvan

2

没有更多的代码示例我收集代码是在测试中使用Spring。所以我相信这个错误的原因是与Spring使用有关,这似乎产生了JDK代理($Proxy88)。

Powermock工作的方式是通过在新的类加载器中运行JUnit测试来修改这些类的字节码,但不幸的是它只能修改真实文件中的字节码,或者至少从因为java不能访问已经加载到JVM中的字节码,因此可以读取类二进制文件。 (可以通过有限的方式与代理商合作)。

由于JDK代理不在磁盘上,因此无法读取或复制到特定的Powermock类加载器。

您正在编写的测试不是单元测试,因为它使用Spring上下文运行。您可能需要先写一个真实的单元测试。然后一些集成测试,其中你不需要模拟

你也应该避免使用静态,因为它是一个可测试性的噩梦。您应该以静态调用不需要模拟的方式重写生产代码。

干杯,

+0

感谢您的解释。 – ejaenv

0
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = "classpath:/test-servlet.xml") 
public class ControlCenterManagerImplTest { 

@Rule 
public PowerMockRule rule = new PowerMockRule(); 

//Powermock agent initialization not required and using maven dependency specified above by BHUVAN we can execute Power mock using spring.} 
4

用powermock-module-junit4-ru替换powermock-module-junit4-rule LE-剂。

<dependency> 
    <groupId>org.powermock</groupId> 
    <artifactId>powermock-module-junit4-rule-agent</artifactId> 
    <scope>test</scope> 
</dependency> 

基于代理的引导程序和基于类加载的引导程序之间的主要区别在于您不会遇到类加载问题。

+0

谢谢@ tak3shi它为我工作!另外我需要使用-javaagent标志。 – ejaenv