标题单元测试及示例说明(Mock,Mockito,PocwerMockito)
单元测试总结文档
一 前置配置及说明
1. JUnit4Test Class模板配置
File–>Settings–>Editor–>File and Code Templates -->Code–>JUnit4Test Class
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.HashMap;
import java.util.Map;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
#parse("File Header.java")
@RunWith(PowerMockRunner.class)
public class ${name}{
@InjectMocks//创建一个需要测试的对象
//function在具体测试方法中需要改成具体的className
private ${CLASS_NAME} function;
@Mock//模拟一个对象,注入到@InjectMocks的对象中
private Manager manager;
//Manager,需要改成测试类中对应的@Autowired 类
${BODY}
}
2. 测试类配置
File–>Settings–>Editor–>File and Code Templates -->code–>JUnit4 Test Class
/*IDEA 设置测试类方法体路径*/
File-->Settings-->Editor-->File and Code Templates -->code-->JUnit4 Test Class
import com.tesla.monitor.filter.FunchtionCounterInterceptor;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#parse("File Header.java")
@RunWith(PowerMockRunner.class)//启动
public class ${NAME}{
@InjectMocks//创建一个测试对象
private ${CLASS_NAME} function;
@Mock//模拟一个对象,注入到@InjectMocks的对象中
private Manager manager;
${BODY}
}
3. 测试类测试方法配置
File–>Settings–>Editor–>File and Code Templates -->code–>JUnit4 Test Method
/*IDEA 设置测试类方法路径*/
File-->Settings-->Editor-->File and Code Templates -->code-->JUnit4 Test Method
/**
*${NAME} 方法测试单元
*/
@org.junit.Test
public void ${NAME}BranchOne(){
/******************代理 非静态 Manager 出入参固定*************/
//代理调用返回
//doReturn(new Integer(100)).when(manger).getCurrentCount(anyString());
/****************************调用测试方法***********************/
//A reA = new A();
// Map<String ,Object> s = function.sysStatusProbe(reA);
/****************************验证***********************/
//Assert.assertEquals("running",s.get("sysStatus"));
${BODY}
}
4. SetUp Method配置
File–>Settings–>Editor–>File and Code Templates -->code–>JUnit4 SetUp Method
/*IDEA 设置setup路径*/
File-->Settings-->Editor-->File and Code Templates -->code-->JUnit4 SetUp Method
@org.junit.Before
public void setUp() throws Exception{
//调用静态类时 加载该方法 做动态代理
PowerMockito.mockitoStatic(ReturnMessageUtil.class);
/********代理 returnMessage 方法*****/
PowerMockito.when(ReturnMessageUtil.returnMessage(anyString(),angString()).thenReturn(new HashMap<String,Object>());
${BODY}
}
二 生成测试报告
//Edit Configurations 指令
//Command line
clean test -Dmaven.test.failure.ignore=true
-f pom.xml
- 报告地址(html)
/target/site/jacoco/index.html
三 测试案例Demo
1. 情景一 Function.class
/**
*Function.class
*/
@Functions
public class AFunction{
@Autowired
private AManager amanager;
/**
*待测试方法
*/
public Map<String , Object> aFunction(Object obj){
//${BODY}
}
}
/**
*FunctionTest.class
*/
@RunWith(PowerMockRunner.class)//启动
public class AFunctionTest{
@InjectMocks//创建一个被测试对象
private AFunction aFunction;
@Mock//注入InjectMocks对象里面
private AManager amanager;
/**
*AFunctionTest 方法测试单元
*/
public void AFunctionTestBranchOne(){
//${TESTBODY}
/***********代理 非静态 Manager 出入参固定*************/
//1.代理调用返回参数
//doReturn(new Integer(100)).when(manger).getCurrentCount(anyString());
/***********************调用测试方法***********************/
//A reA = new A();
// Map<String ,Object> s = function.aFunction(reA);
/****************************验证***********************/
//Assert.assertEquals("running",s.get("sysStatus"));
}
}
2. 情景二 Function.class 内有使用static,final方法
/**
*FunctionTest.class
*/
@RunWith(PowerMockRunner.class)//启动
@PrepareForTest({Static.class})//静态类
public class AFunctionTest{
@InjectMocks//创建一个被测试对象
private AFunction aFunction;
@Mock//注入InjectMocks对象里面
private AManager amanager;
@test
public AFunction(){
//${TESTBODY}
/******************代理 静态 static 出入参固定*************/
//1.代理调用静态
PowerMockito.mockStatic(static.class);
PowerMockito.when(Static.getProperties(anyObject())).thenReturn(someThing);
/**************************调用测试方法***********************/
A reA = new A();
Map<String ,Object> s = function.aFunction(reA);
/****************************验证***********************/
Assert.assertEquals("running",s.get("sysStatus"));
}
}
3. 情景三 Enum.class
/**
*Enum.class
*/
public enun AaEnum{
OPINION_YES("1","是"),
OPINION_NO("0","否");
AaEnum(String code,String value){
this.code = code;
this.value = value;
}
public String getCode(){
return code;
}
}
/**
*EnumTest.class
*/
@RunWith(PowerMockRunner.class)//启动注解
public enun AaEnumTest{
/**
*getCode 方法测试单元
*/
public void getCodeBranchOne(){
/************* 调用测试方法 **********/
String str = AaEnum.OPINION_YES.getCode();
/************* 验证 ***********/
Assert.assertNotNull(str);
}
}
4. 情景四 测试类中私有属性需要赋值才能满足测试分支时
/**
*Function.class
*私有属性需要赋值的情况
*/
@Functions
public class AFunction{
@Autowired
private ApplicationContext applicationContext;
/**
*待测试方法
*/
public Map<String , Object> aFunction(Object obj){
//${BODY}
}
}
/**
*FunctionTest.class
*/
@RunWith(PowerMockRunner.class)//启动
public class AFunctionTest{
@InjectMocks//创建一个被测试对象
private AFunction aFunction;
@Mock//注入InjectMocks对象里面
private AManager amanager;
/**
*AFunctionTest 方法测试单元
*/
public void AFunctionTestBranchOne(){
//${TESTBODY}
/***********代理 非静态 Manager 出入参固定*************/
//1.代理调用返回参数
//doReturn(new Integer(100)).when(manger).getCurrentCount(anyString());
//设置私有属性固定值,以满足我们所需的测试条件
ApplicationContext applicationContext = PowerMockito.mock(ApplicationContext.class);
MemberModifier.field(AFunction.class, "applicationContext").set(aFunction,applicationContext);
/***********************调用测试方法***********************/
//A reA = new A();
// Map<String ,Object> s = function.aFunction(reA);
/****************************验证***********************/
//Assert.assertEquals("running",s.get("sysStatus"));
}
}
5. 情景五 Abstract.class
抽象类的单元测试编写时,无需将被测试类@InjectMocks,直接将抽象类在测试类中设为私有属性即可
public abstract class AbstractFunctionTest{
private AbstractFunction abstractFunction;
}
6. 情景六 修改logger属性
public class Person {
private final Logger logger = LoggerFactory.getLogger(getClass())
if(logger.isDebugEnabled()){
logger.debug("********")
}
}
/**
*logger存在分支情况,若想让括号内为true,代理Logger
*/
@InjectMocks
private Person person;
Logger logger = PowerMockito.mock(Logger.class);//代理logger
when(logger.isDebugEnable()).thenReturn(true);//代理返回
MemberModifier.filed(Person.class,"logger")
.set(person,logger)//修改成员属性
7. 情景七 测试类中有静态方法
public class person{
/**
*待测试方法
*/
public static String getName(){
}
}
@RunWith(PowerMockRunner.class)//启动
public class personTest{
@Test
public void getName(){
/***********************调用测试方法***********************/
String s = Person.getName();
/****************************验证***********************/
Assert.assertNotNull(s);
}
}
8. 情景八 常量类
/**
*被测试类
*/
public class ArcConstants{
public static final String SYS_MODULE_CODE = "moduleCode";
public static final String SYSTEM_INSTALL = "x22_INSTALL";
}
@RunWith(PowerMockRunner.class)//启动
public class ArcConstantsTest{
@Test
public void test(){
ArcConstants arcConstants = new ArcConstants();
}
}
四 不适宜做代理的情况
1. 被测试类内有new Class()的情况;
待测试类内部依赖new Class()返回值;
待测试类内部依赖
2. 被测试类内有继承父类的情况,父类方法无法代理;
3. 被测试类有依赖抽象类的情况下,无法代理;
mock抽象类时,没有走真正的方法,jacoco代码会覆盖不到,所以不建议mock