PowerMock用法

来源:互联网 发布:淘金网络 编辑:程序博客网 时间:2024/03/29 13:10

         最近一直在用PowerMockUnit testObject 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 StringgetMsg(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"));

    }

 

}

 

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

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

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

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

                            java.lang.AssertionError:

                                   Unexpectedmethod call getTest("test"):

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

 

(二)  Mock class static method

 

public class IdGenerator {

   public static long generateNewId() {

      return System.currentTimeMillis();

   }

}

public class StaticClassSample{

    public longregisterService(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 = newStaticClassSample().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 StringmodifyDataMethodName = "modifyData";

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

            final StringexpectedDataId = "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 = newFile(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 = newPersistenceManager();

 

                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的一些比较基本的用法。

原创粉丝点击