首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用PowerMock获取PowerMock,用Mockito实现JUnit中的PowerRule

用PowerMock获取PowerMock,用Mockito实现JUnit中的PowerRule
EN

Stack Overflow用户
提问于 2012-08-30 05:25:21
回答 4查看 21.6K关注 0票数 7

我已经将PowerMock和PowerRule集成到了JUnit和Mockito中。

下面是我的依赖关系:

代码语言:javascript
复制
<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>

我的考试课是:

代码语言:javascript
复制
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 正在调用我需要模拟的静态方法。当我运行我的测试用例时,我得到了

全堆栈跟踪:

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),java.lang.ClassLoader.loadClass(ClassLoader.java:252),java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320),java.langorg.powermock.api.support.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:66),org.powermock.api.support.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:26),org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:243),org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128),org.powermock.classloading,java.lang.Class.forName(Class.java:247)。org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128),org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248),org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128),org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248),org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128),org.powermock.classloading。org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128),org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248),org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128),org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248),org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128),org.powermock.classloading。org.powermock.classloading.DeepCloner.clone(DeepCloner.java:69) at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:89) 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) DeepCloner.clone(DeepCloner.java:82)在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.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.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) at org.junit.runners.ParentRunner.run(ParentRunner.java:236)在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) at 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.org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)的runTests(RemoteTestRunner.java:683):javassist.NotFoundException:$Proxy88 at javassist.ClassPool.get(ClassPool.java:436) at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:180) . 46

如果我将依赖项更改为

代码语言:javascript
复制
<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 (删除所以问题,要求10k)。

我甚至尝试过使用javassist版本15,但这也有同样的问题。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-10-24 05:09:26

自己找出了解决办法:

只使用下面的依赖项(用于电源模拟和电源规则)

代码语言:javascript
复制
    <!-- 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>

现在我没有得到上述任何一个例外。

票数 8
EN

Stack Overflow用户

发布于 2014-01-31 15:20:00

将powermock模块-Junit4-规则替换为powermock模块-duit4-规则代理。

代码语言:javascript
复制
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4-rule-agent</artifactId>
    <scope>test</scope>
</dependency>

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

票数 4
EN

Stack Overflow用户

发布于 2012-08-30 08:07:18

如果没有更多的代码示例,我就会发现代码在测试中使用Spring。因此,我认为造成此错误的原因是与Spring有关,Spring似乎确实生成了JDK代理( $Proxy88)。

Powermock的工作方式是在新的类加载器中运行JUnit测试,以便修改这些类的字节码,不幸的是,只能从真正的文件中修改字节码,或者至少可以从可以读取类二进制文件的位置修改字节码,因为java不能访问JVM中已经加载的字节码。(可能与代理人有一定的关系)。

由于JDK代理不存在于磁盘上,因此无法读取它们,也不能将它们复制到特定的Powermock类加载器中。

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

此外,您应该避免使用静力学,因为这是一个可测试的噩梦。您应该以不需要对静态调用进行模拟的方式重写生产代码。

干杯,

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12190377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档