`

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常用方法.

    在测试类上使用`@PrepareForTest`注解可以指定哪些类需要被PowerMock处理,这包括需要模拟的类或包含静态方法的类。 8. **使用`@RunWith(PowerMockRunner.class)`** 要使用PowerMock,你需要在测试类上添加`@Run...

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

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

    利用PowerMock模拟静态方法和私有方法的示例

    下面是一段使用PowerMock模拟静态方法和私有方法的示例代码: ```java import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org....

    powermock

    PowerMock 是一个强大的 Java 测试框架的扩展工具,它允许开发者在单元测试中模拟静态方法、构造函数、最终类和删除静态初始化器等通常难以测试的场景。在 Java 单元测试领域,EasyMock 和 JUnit 是两个常用库,...

    汪文君powermock实战教学

    2. **PowerMock基本用法**:讲解如何创建mock对象,模拟方法调用,以及如何配置期望行为。这是理解PowerMock核心功能的关键。 3. **Mock局部变量**:在传统mock框架中,局部变量的模拟是困难的。PowerMock允许你对...

    使用PowerMock来Mock静态函数

    标题“使用PowerMock来Mock静态函数”指的是如何利用PowerMock库来对Java中的静态方法进行模拟测试。静态方法由于其非实例化特性,通常难以通过常规的单元测试方式进行隔离和测试,因为它们不依赖于对象的状态。...

    powermock依赖jar文件.rar

    这个压缩包可能是用户在尝试多种方法后,最终成功配置PowerMock并进行单元测试的成果,为了方便其他开发者使用和避免重蹈覆辙,他分享了这些必要的依赖。 描述中提到的"网上找了好多powermock的例子都不好用,一怒...

    PowerMock实战

    标题“PowerMock实战”意味着本书将深入介绍PowerMock的使用方法,帮助读者理解和掌握如何在实际开发中运用PowerMock提高代码测试的健壮性和完整性。描述中的“帮助初学者彻底了解PowerMock的使用”表明本书适合那些...

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

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

    powermock源码 详细学习好帮手

    3. **类加载器的使用**:PowerMock通过自定义类加载器来实现对类的控制,包括重定义类的行为,这对于模拟静态方法和final类至关重要。 4. **Bytecode工程**:PowerMock使用ASM库来操作字节码,这是实现其强大功能的...

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

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

    powermock单元测试

    在提供的压缩包"powermock+静态和私有方法测试代码"中,很可能包含了一些示例代码,展示了如何使用PowerMock进行这类测试。通过分析这些代码,我们可以更深入地理解PowerMock的工作原理和使用方式。 总的来说,...

    PowerMock实战手册

    《PowerMock实战手册》是一本专注于使用PowerMock进行单元测试的指南,结合了Junit测试框架和Mockito库,为...通过学习这本书,你不仅可以掌握PowerMock的用法,还能深入理解单元测试的最佳实践,提升你的编程技能。

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

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

    powerMock的测试样例集合

    在“powerMock的测试样例集合”中,我们可以深入理解并掌握PowerMock的各种用法。 1. **Mock Static Methods**: 在Java中,静态方法是不能被继承或覆写的,因此在单元测试中很难模拟其行为。PowerMock提供`@...

    PowerMock.zip

    开发者可以使用@PrepareForTest 注解来指定哪些类需要被PowerMock处理,然后在测试方法中使用PowerMockito的各种API来设置和验证模拟行为。 例如,以下是一个简单的PowerMock示例: ```java @RunWith...

    powermock-mockito-junit-1.6.2.zip

    5. 使用PowerMock的API模拟静态方法、final类或方法等。 6. 编写测试方法,调用要测试的代码,并使用Mockito验证方法调用是否符合预期。 通过以上步骤,开发者可以利用PowerMock的强大功能,结合Mockito的简洁性和...

    powermock maven respo

    PowerMock Maven Repository是一个重要的开发工具资源库,它主要服务于Java开发者,特别是那些使用PowerMock框架进行单元测试的人员。PowerMock是一个强大的库,允许开发者模拟静态方法、构造函数、删除final修饰、...

Global site tag (gtag.js) - Google Analytics