`

PowerMock用法

阅读更多
最近一直在用PowerMock做Unit test的Object mock(对象模拟)。总结了一些经验和发现了一些须要注意事项,俗语说的好“好记性不如烂笔头”,为方便日后参考,于是把它们写下来。

         说到PowerMock不得不提EasyMock, 如果日常工作中要实现一些对象的Mock(如,写一些Unit test),大家对EasyMock应该会有所了解, 正是由于EasyMock在复杂情况下的表现不佳,则有了后面的PowerMock。这里简单罗列一下EasyMock一些不足之处:

1) 3.0以前只能Mock interface不能Mock Class。(3.0以前要引放Mock class extension实现Mock class)。

2)不能够Mock 静态方法,final方法,private方法和构造函数。



然后这些不足之处对PowerMock来说是很容易实现的,因为PowerMock实现机制与EasyMock不一样,EasyMock是用的proxy的方式实现在的Mock,而PowerMock则是使用Cglib直接修改的字节码。



现在来说一下一些具体一点用法:

(一)   Mock class public method



public class ExampleClass {

    public String getMsg(String s){

       if ("yes".equals(s)){

           return "yes";

       } else {

           return "no";

       }

    }

  

    public String getTest(String s){

       return this.getMsg(s);

    }

}

       如上所示类,请见unit teset

@RunWith(PowerMockRunner.class)

@PrepareForTest({ExampleClass.class})

public class ExampleClassTest {



    @Test

    public void testGetMsg() {    

       ExampleClass ec = PowerMock.createPartialMock(ExampleClass.class, "getMsg");

       EasyMock.expect(ec.getMsg("test")).andReturn("PowerMock");

       PowerMock.replay(ec);

     

       assertEquals("PowerMock", ec.getTest("test"));

    }



}



本例用PowerMock mock了ExampleClass的部分method getMsg(…),由上看出本类实则有两个方法,另一个是getTest(…)。如果采用如下代码

ExampleClass ec = PowerMock.createMock(ExampleClass.class);

       EasyMock.expect(ec.getMsg("test")).andReturn("PowerMock");

后面的ec.getTest(“test”)将会抛异常

                            java.lang.AssertionError:

                                   Unexpected method call getTest("test"):

因为此时mock对象ec仅被指定有一个方法getMsg。



(二)   Mock class static method



public class IdGenerator {

   public static long generateNewId() {

      return System.currentTimeMillis();

   }

}

public class StaticClassSample {

    public long registerService(Object service) {

       final long id = IdGenerator.generateNewId();

       return id;

    }

}



@RunWith(PowerMockRunner.class)

@PrepareForTest( {StaticClassSample.class, IdGenerator.class})

public class StaticClassSampleTest { 

    @Test

    public void testRegisterService() throws Exception {

            long expectedId = 42;

            PowerMock.mockStatic(IdGenerator.class);

EasyMock.expect(IdGenerator.generateNewId()).andReturn(expectedId);

            PowerMock.replay(IdGenerator.class);

            long actualId = new StaticClassSample().registerService(new Object());

            Assert.assertEquals(expectedId, actualId);

            PowerMock.verify(IdGenerator.class);

    }

}

(三)   Mock class private method



public class DataService {



    public boolean replaceData(final String dataId, final byte[] binaryData) {

            return modifyData(dataId, binaryData);

    }

    public boolean deleteData(final String dataId) {

            return modifyData(dataId, null);

    }

  

    private boolean modifyData(final String dataId, final byte[] binaryData) {

            return true;

    }

}



@RunWith(PowerMockRunner.class)

@PrepareForTest( {DataService.class})

public class DataServiceTest {

    @Test

    public void testReplaceData() throws Exception {

            final String modifyDataMethodName = "modifyData";

            final byte[] expectedBinaryData = new byte[] { 42 };

            final String expectedDataId = "id";

            DataService tested = createPartialMock(DataService.class, modifyDataMethodName);

            expectPrivate(tested, modifyDataMethodName, expectedDataId,

                            expectedBinaryData).andReturn(true);

            replay(tested);

            Assert.assertTrue(tested.replaceData(expectedDataId, expectedBinaryData));

            verify(tested);

    }

}



(四)   Mock class constructor



public class PersistenceManager {



    public boolean createDirectoryStructure(String directoryPath) {

            File directory = new File(directoryPath);



            if (directory.exists()) {

                    throw new IllegalArgumentException("/"" + directoryPath + "/" already exists.");

            }



            return directory.mkdirs();

    }

}



@RunWith(PowerMockRunner.class)

@PrepareForTest( PersistenceManager.class )

public class PersistenceManagerTest {



        @Test

        public void testCreateDirectoryStructure_ok() throws Exception {

                final String path = "directoryPath";

                File fileMock = PowerMock.createMock(File.class);



                PersistenceManager tested = new PersistenceManager();



                PowerMock.expectNew(File.class, path).andReturn(fileMock);



                EasyMock.expect(fileMock.exists()).andReturn(false);

                EasyMock.expect(fileMock.mkdirs()).andReturn(true);



                PowerMock.replay(fileMock, File.class);



                Assert.assertTrue(tested.createDirectoryStructure(path));



                PowerMock.verify(fileMock, File.class);

        }

}





上面就是PowerMock的一些比较基本的用法
分享到:
评论

相关推荐

    powermock-core-2.0.9-API文档-中英对照版.zip

    使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。

    powermock-api-mockito2-2.0.9-API文档-中英对照版.zip

    使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。

    powermock-api-support-2.0.9-API文档-中英对照版.zip

    使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。

    powermock-module-junit4-2.0.9-API文档-中英对照版.zip

    使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。

    powermock单元测试

    powermock1.4.9.jar和powermock测试静态方法和私有方法的测试代码,大家都知道easymock不能测试这些,配合使用和单元测试更加完善。

    powermock-cover.zip

    使用powermock+jacoco,测试静态方法,测试覆盖率。环境是:IDEA+maven。 直接执行:mvn clean install,然后查看覆盖率:powermock-cover\target\site\jacoco\index.html

    powermock-module-junit4-common-2.0.9-API文档-中英对照版.zip

    赠送jar包:powermock-module-junit4-common-...使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双

    使用PowerMock来Mock静态函数

    NULL 博文链接:https://never-forget.iteye.com/blog/1717297

    powermock-mockito-demo:使用springboot的powermock-mockito-demo

    但是官网powermock 1.7.x只支持2.8.0-2.8.9,如果使用默认引入版本,会出现找不到某些方法的异常. 需要自定义mockito-core为相应版本。 ServiceAspect只是为了验证当spy实体在被代理的情况下powermockito是否还会生效...

    powermock-reflect-2.0.9-API文档-中英对照版.zip

    使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。

    MockingPresentation:包含 Mockito 和 PowerMock 使用示例

    模拟演示包含 Mockito 和 PowerMock 用法的示例。 请访问获取更多信息

    junit_powermock:一种简单的 JUnit 单元测试方法,以及 Powermock 的使用

    junit_powermock

    powermock-legacy:PowerMock-Legacy 是 PowerMock for Java 1.4 的复刻版

    介绍即使在 2011 年,仍有许多遗留项目需要 Java 1.4(特别是在大型保守企业中),而且这些项目中的大多数在设计时都没有考虑到可测试性,因此它们倾向于使用和滥用静态(有时是最终)方法。 这些方法不容易用 ...

    pow源码java-powermock-examples:Java世界的开源模拟库

    pow源码java PowerMock是Java世界的开源模拟库。 它扩展了现有的模拟框架(例如和),以向它们添加甚至更强大的功能。 PowerMock使我们能够为最不可测试的代码编写良好...但是使用PowerMock,我们可以模拟几乎任何类。

    power mockito学习资料

    PowerMock使用一个自定义类加载器和字节码操作来模拟静态方法,构造函数,final类和方法,私有方法,去除静态初始化器等等。通过使用自定义的类加载器,简化采用的IDE或持续集成服务器不需要做任何改变。熟悉...

    powermock-reflect-2.0.9.jar中文-英文对照文档.zip

    # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-javadoc-API文档-中文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作...

    powermock-core-2.0.9.jar中文-英文对照文档.zip

    # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-javadoc-API文档-中文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作...

    powermock-api-support-2.0.9.jar中文-英文对照文档.zip

    # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-javadoc-API文档-中文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作...

    powermock-api-mockito2-2.0.9.jar中文-英文对照文档.zip

    # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-javadoc-API文档-中文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作...

    powermock-module-junit4-2.0.9.jar中文-英文对照文档.zip

    # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-javadoc-API文档-中文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作...

Global site tag (gtag.js) - Google Analytics