PowerMockito的基本使⽤解析
PowerMockito经常会结合Mockito使⽤,先说⼀下这2个的介绍:
1.Mockito和PowerMockito的简介
Mockito和PowerMockito是什么东西呢?他们有什么作⽤呢?
Mocktio和PowerMockito都是Mock的⼯具类,主要是Java的类库,Mock就是伪装的意思。
他们适⽤于单元测试中,对于单元测试来说,我们不希望依赖于第三⽅的组件,⽐如数据库、Webservice等。在写单元测试的时候,我们如果遇到了这些需要依赖第三⽅的情况,我们可以使⽤Mock的技术,伪造出来我们⾃⼰想要的结果。
对于Java⽽⾔,mock的对象主要是Java ⽅法和 Java类。
下⾯我就介绍⼀下怎么使⽤Mockito和PowerMockito去进⾏Mock。
2.Mockito和PowerMockito的区别
在我看来,PowerMockito是Mockito的⼀种增强,他们的PowerMockito可以调⽤Mockito的⽅法,但是对
于Mocktio不能Mock 的对象或者⽅法,我们可以使⽤PowerMockito来实现。
⽐如Mockito不能⽤于static Method, final method, 枚举类, private method,这些我们都可以⽤PowerMockito来实现,当PowerMockito和mockito结合使⽤的时候,我们需要考虑兼容性的问题。
两者的版本需要兼容
Mockito PowerMockito
2.8.9+  2.x
2.8.0-2.8.9  1.7.x
2.7.5  1.7.0RC4
2.4.0  1.7.0RC2
2.0.0-beta - 2.0.42-beta1.6.5-1.7.0RC
1.10.8 - 1.10.x  1.6.2 -
2.0
1.9.5-rc1 - 1.9.5  1.5.0 - 1.5.6
1.9.0-rc1 & 1.9.0  1.4.10 - 1.4.12
1.8.5  1.3.9 - 1.4.9
1.8.4  1.3.7 & 1.3.8
1.8.3  1.3.6
1.8.1 & 1.8.2  1.3.5
spring framework是什么意思1.8  1.3
1.7  1.
2.5
3.具体⽤法
本⽂实现实现需要构造的接⼝和需要返回值的接⼝
引⼊依赖
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId&kito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
</dependencies>
需要Mock的类:
ProcessDB.java
package k.simple.vo;
public class ProcessDB {
public ProcessDB(String ss){
System.out.println(ss + " Enter ProcessDB ...");
}
public ProcessDB(){
System.out.println("Enter ProcessDB ...");
}
public void getResultOfConnectDBNoReturn(String ss) {
System.out.println(ss + " Enter getResultOfConnectDBNoReturn ...");    }
public String getResultOfConnectDB() {
return "haha, Really went to the database";
}
}
需要测试的类:
IUserService.java
package k.simple.user;
public interface IUserService {
public String testedMehtod();
}
UserServiceImpl.java
package k.simple.user.impl;
import org.springframework.stereotype.Service;
import k.simple.user.IUserService;
import k.simple.vo.ProcessDB;
@Service
public class UserServiceImpl implements IUserService {
@Override
public String testedMehtod(){
System.out.println("Enter UserServiceImpl testedMehtod ...");
ProcessDB processDB = new ProcessDB("BB");
ResultOfConnectDB();
}
}
BussinessService.java
package k.simple.user.impl;
import k.simple.vo.ProcessDB;
public class BussinessService {
public String testedMehtod() {
System.out.println("Enter BussinessService testedMehtod ...");
ProcessDB processDB = new ProcessDB("BB");
ResultOfConnectDB();
}
}
测试类:
MockSpringSimpleTest.java
package st;
MessageFormat;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
kito.InjectMocks;
kito.Mock;
kito.MockitoAnnotations;
import org.kito.PowerMockito;
import lassloader.annotations.PrepareForTest;
import dules.junit4.PowerMockRunner;
import dules.junit4.PowerMockRunnerDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import st.context.ContextConfiguration;
import st.context.junit4.SpringJUnit4ClassRunner;
import k.simple.user.IUserService;
import k.simple.user.impl.BussinessService;
import k.simple.user.impl.UserServiceImpl;
import k.simple.vo.ProcessDB;
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)//Spring上下⽂
@PrepareForTest({BussinessService.class,UserServiceImpl.class})
@ContextConfiguration(locations = {"l"})
public class MockSpringSimpleTest {
//使⽤Spring上下⽂
@Autowired
IUserService userService;
@Mock
ProcessDB processDB;
//不使⽤Spring上下⽂时,使⽤该注解
@InjectMocks
private BussinessService bussinessService;
@Before
public void initMocks() throws Exception {
MockitoAnnotations.initMocks(this);
//ReflectionTestUtils.setField(userService, "processDB", processDB);
PowerMockito.whenNew(ProcessDB.class).withArguments("BB").thenReturn(processDB);        // PowerMockito.whenNew(ProcessDB.class).withNoArguments().thenReturn(processDB);    }
@Test
public void mockConnectDB() {
String aa = "haha, everything is fake";
PowerMockito.ResultOfConnectDB()).thenReturn(aa);
PowerMockito.doNothing().when(processDB).getResultOfConnectDBNoReturn("AA");
System.out.stedMehtod());
Assert.assertEquals("haha, everything is fake", stedMehtod());
}
@Test
public void mockConnectDB2() {
try {
String aa = "haha, everything is fake";
PowerMockito.ResultOfConnectDB()).thenReturn(aa);
PowerMockito.doNothing().when(processDB).getResultOfConnectDBNoReturn("AA");
System.out.stedMehtod());
Assert.assertEquals("haha, everything is fake", stedMehtod());
} catch (Exception ex) {
System.out.println("--- getMessage ---");
System.out.Message());
System.out.println();
System.out.println("--- toString ---");
System.out.String());
System.out.println();
//            System.out.println("--- printStackTrace ---");
//            StringWriter stringWriter = new StringWriter();
//            PrintWriter printWriter = new PrintWriter(stringWriter);
/
/            ex.printStackTrace(printWriter);
//            System.out.String());
//            System.out.println();
System.out.println("--- printStackTrace DIY ---");
System.out.Class().getName() + ": " + ex.getMessage());
StringBuilder sbException = new StringBuilder();
for (StackTraceElement ele : ex.getStackTrace()) {
sbException.append(MessageFormat.format("\tat {0}.{1}({2}:{3})\n",
}
System.out.println(sbException);
sbException = null;
//            stringWriter = null;
//            printWriter = null;
}
}
}
扫描注⼊xml
最后l
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance"
xmlns:context="/schema/context"
xsi:schemaLocation="
/schema/beans
/schema/beans/spring-beans.xsd
/schema/context
/schema/context/spring-context.xsd">
<context:component-scan base-package="k.simple"/>
</beans>
对于没有实现类,但⼜被依赖的接⼝,在l添加如下内容 (本⽂不需要):<bean name="iXxService" class="kito.Mockito" factory-method="mock">
<constructor-arg value="k.simple.api.IXxService"/>
</bean>
同时在测试类⾥⾯添加下⾯的代码:
@Mock
iXxService iXxService;
在 @Before⾥⾯添加下⾯的代码
ReflectionTestUtils.setField(userService, "iXxService", iXxService);
测试结果
PowerMockito的使⽤技巧
当IT中有些依赖组件⽆法正常集成,需要mock⽀持测试,可以使⽤power mockito。
特别注意:
当对⼀个对象进⾏powermockito,应该在prepare⽅法,统⼀mock这个对象。然后在其他⽅法,分别进⾏调⽤when,否则,多个⽅法内进⾏mock,会出错。
⽐如有个 Service处于IT case的底层,普通的mock根本mock不进去,但我们⼜不能为了集成测试,为这个testcase单独开⼀个⼝⼦,注⼊mock对象。power mockito强⼤的mock能⼒在这⾥可以⽤上。
⽐如:
我的mock对象impalaService它在schmaMessagehandler类⾥new出来的,则需要加上注解。
⾸先在test 类的开头,加上注解头部,头部类是mock对象所在类。
@RunWith(PowerMockRunner.class)
@PrepareForTest({HttpClient.class,SchemaMessageHandler.class})
其次:
PooledImpalaService impalaService = k(PooledImpalaService.class);
PowerMockito.whenNew(PooledImpalaService.class).withArguments((ConfigurationanyObject()).thenReturn(impalaService);
doNothing().when(impalaService).createTable(anyString(),(Schema) anyObject());
使⽤powermockito,注意在⽤any()参数时候,⽐如
doNothing().when(impalaService).createTable(anyString(),(Schema) anyObject());
参数列表中,只要⼀个使⽤了any(),any****,则所有参数都要⽤any相关的参数,否则mock不成功。
总的来说,在it当中,只有你想mock⼀个对象,⼀定可以,⽐如你在A类中⽤到了B类,那么在prepareForTest中增加A类的注解。
如下:
@PrepareForTest({A.class})然后,在it中声明⼀个B类,B b = k(B.class);这时候,就可以指定b的⽅法的返回值,或 PowerMockit.doNothing().when(b).⽅法名(),让该⽅法什么也不做。
最后,再讲A实例化。PowerMockit是讲究mock设置顺序的。⼀定要注意。
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。