最近一直在用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的一些比较基本的用法
分享到:
相关推荐
在测试类上使用`@PrepareForTest`注解可以指定哪些类需要被PowerMock处理,这包括需要模拟的类或包含静态方法的类。 8. **使用`@RunWith(PowerMockRunner.class)`** 要使用PowerMock,你需要在测试类上添加`@Run...
使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。
下面是一段使用PowerMock模拟静态方法和私有方法的示例代码: ```java import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org....
PowerMock 是一个强大的 Java 测试框架的扩展工具,它允许开发者在单元测试中模拟静态方法、构造函数、最终类和删除静态初始化器等通常难以测试的场景。在 Java 单元测试领域,EasyMock 和 JUnit 是两个常用库,...
2. **PowerMock基本用法**:讲解如何创建mock对象,模拟方法调用,以及如何配置期望行为。这是理解PowerMock核心功能的关键。 3. **Mock局部变量**:在传统mock框架中,局部变量的模拟是困难的。PowerMock允许你对...
标题“使用PowerMock来Mock静态函数”指的是如何利用PowerMock库来对Java中的静态方法进行模拟测试。静态方法由于其非实例化特性,通常难以通过常规的单元测试方式进行隔离和测试,因为它们不依赖于对象的状态。...
这个压缩包可能是用户在尝试多种方法后,最终成功配置PowerMock并进行单元测试的成果,为了方便其他开发者使用和避免重蹈覆辙,他分享了这些必要的依赖。 描述中提到的"网上找了好多powermock的例子都不好用,一怒...
标题“PowerMock实战”意味着本书将深入介绍PowerMock的使用方法,帮助读者理解和掌握如何在实际开发中运用PowerMock提高代码测试的健壮性和完整性。描述中的“帮助初学者彻底了解PowerMock的使用”表明本书适合那些...
使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。
3. **类加载器的使用**:PowerMock通过自定义类加载器来实现对类的控制,包括重定义类的行为,这对于模拟静态方法和final类至关重要。 4. **Bytecode工程**:PowerMock使用ASM库来操作字节码,这是实现其强大功能的...
使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。
在提供的压缩包"powermock+静态和私有方法测试代码"中,很可能包含了一些示例代码,展示了如何使用PowerMock进行这类测试。通过分析这些代码,我们可以更深入地理解PowerMock的工作原理和使用方式。 总的来说,...
《PowerMock实战手册》是一本专注于使用PowerMock进行单元测试的指南,结合了Junit测试框架和Mockito库,为...通过学习这本书,你不仅可以掌握PowerMock的用法,还能深入理解单元测试的最佳实践,提升你的编程技能。
使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。
在“powerMock的测试样例集合”中,我们可以深入理解并掌握PowerMock的各种用法。 1. **Mock Static Methods**: 在Java中,静态方法是不能被继承或覆写的,因此在单元测试中很难模拟其行为。PowerMock提供`@...
开发者可以使用@PrepareForTest 注解来指定哪些类需要被PowerMock处理,然后在测试方法中使用PowerMockito的各种API来设置和验证模拟行为。 例如,以下是一个简单的PowerMock示例: ```java @RunWith...
5. 使用PowerMock的API模拟静态方法、final类或方法等。 6. 编写测试方法,调用要测试的代码,并使用Mockito验证方法调用是否符合预期。 通过以上步骤,开发者可以利用PowerMock的强大功能,结合Mockito的简洁性和...
PowerMock Maven Repository是一个重要的开发工具资源库,它主要服务于Java开发者,特别是那些使用PowerMock框架进行单元测试的人员。PowerMock是一个强大的库,允许开发者模拟静态方法、构造函数、删除final修饰、...