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的一些比较基本的用法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值