PowerMock使用详解
1. PowerMock是什么?
PowerMock是一个Java模拟框架,用于解决测试问题。
举个例子,你在使用Junit进行单元测试时,并不想让测试数据进入数据库,怎么办?这个时候就可以使用PowerMock,拦截数据库操作,并模拟返回参数。
2. PowerMock包引入
<!-- PowerMock JUnit 4.4+ Module --> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>2.0.0</version> <scope>test</scope> </dependency> <!-- PowerMock Mockito2 API --> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>2.0.0</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency>
3. 重要注解说明
@RunWith(PowerMockRunner.class) // 告诉JUnit使用PowerMockRunner进行测试 @PrepareForTest({RandomUtil.class}) // 所有需要测试的类列在此处,适用于模拟final类或有final, private, static, native方法的类 @PowerMockIgnore("javax.management.*") //为了解决使用powermock后,提示classloader错误
4. 示例
4.1 普通Mock
/***********************Prepare****************************/
public interface MockMapper {
public int count(MockModel model);
}
@Service
public class MockServiceImpl {
@Autowired
private MockMapper mockMapper;
public int count(MockModel model) {
return mockMapper.count(model);
}
}
/*****************************************************/
@RunWith(PowerMockRunner.class) // 告诉JUnit使用PowerMockRunner进行测试 @PrepareForTest({MockUtil.class}) // 所有需要测试的类列在此处,适用于模拟final类或有final, private, static, native方法的类 @PowerMockIgnore("javax.management.*") //为了解决使用powermock后,提示classloader错误 public class MockExample { // 将@Mock注解的示例注入进来 @InjectMocks private MockServiceImpl mockService; @Mock private MockMapper mockMapper; /** * mock普通方法 */ @Test public void testSelectAppAdvertisementList() { MockModel model = new MockModel(); PowerMockito.when(mockMapper.count(model)).thenReturn(2); Assert.assertEquals(2, mockService.count(model)); } }
2. Mock静态方法
/************************Prepare****************************/ public class MockUtil { private static final Random random = new Random(); public static int nextInt(int bound) { return random.nextInt(bound); } } /***************************************************/
@RunWith(PowerMockRunner.class) // 告诉JUnit使用PowerMockRunner进行测试
@PrepareForTest({MockUtil.class}) // 所有需要测试的类列在此处,适用于模拟final类或有final, private, static, native方法的类
@PowerMockIgnore("javax.management.*") //为了解决使用powermock后,提示classloader错误
public class MockExample {
@Test
public void testStaticMethod() {
PowerMockito.mockStatic(MockUtil.class);
PowerMockito.when(MockUtil.nextInt(10)).thenReturn(7);
Assert.assertEquals(7, MockUtil.nextInt(10));
}
}
3. Mock方法内new出来的对象
/****************************************************/ public boolean makeFile(String path) { File file = new File(path); return file.exists(); } /****************************************************/ @RunWith(PowerMockRunner.class) // 告诉JUnit使用PowerMockRunner进行测试 @PrepareForTest({MockUtil.class, MockServiceImpl.class}) // 所有需要测试的类列在此处,适用于模拟final类或有final, private, static, native方法的类 @PowerMockIgnore("javax.management.*") //为了解决使用powermock后,提示classloader错误 public class MockExample { // 将@Mock注解的示例注入进来 @InjectMocks private MockServiceImpl mockService; @Test public void testNewObject() throws Exception { File file = PowerMockito.mock(File.class); PowerMockito.whenNew(File.class).withArguments("abc").thenReturn(file); PowerMockito.when(file.exists()).thenReturn(true); Assert.assertTrue(mockService.makeFile("abc")); } }