标题单元测试及示例说明(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
@org.junit.Test
public void ${NAME}BranchOne(){
${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);
PowerMockito.when(ReturnMessageUtil.returnMessage(anyString(),angString()).thenReturn(new HashMap<String,Object>());
${BODY}
}
二 生成测试报告
clean test -Dmaven.test.failure.ignore=true
-f pom.xml
- 报告地址(html)
/target/site/jacoco/index.html
三 测试案例Demo
1. 情景一 Function.class
@Functions
public class AFunction{
@Autowired
private AManager amanager;
public Map<String , Object> aFunction(Object obj){
}
}
@RunWith(PowerMockRunner.class)
public class AFunctionTest{
@InjectMocks
private AFunction aFunction;
@Mock
private AManager amanager;
public void AFunctionTestBranchOne(){
}
}
2. 情景二 Function.class 内有使用static,final方法
@RunWith(PowerMockRunner.class)
@PrepareForTest({Static.class})
public class AFunctionTest{
@InjectMocks
private AFunction aFunction;
@Mock
private AManager amanager;
@test
public AFunction(){
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
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;
}
}
@RunWith(PowerMockRunner.class)
public enun AaEnumTest{
public void getCodeBranchOne(){
String str = AaEnum.OPINION_YES.getCode();
Assert.assertNotNull(str);
}
}
4. 情景四 测试类中私有属性需要赋值才能满足测试分支时
@Functions
public class AFunction{
@Autowired
private ApplicationContext applicationContext;
public Map<String , Object> aFunction(Object obj){
}
}
@RunWith(PowerMockRunner.class)
public class AFunctionTest{
@InjectMocks
private AFunction aFunction;
@Mock
private AManager amanager;
public void AFunctionTestBranchOne(){
ApplicationContext applicationContext = PowerMockito.mock(ApplicationContext.class);
MemberModifier.field(AFunction.class, "applicationContext").set(aFunction,applicationContext);
}
}
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("********")
}
}
@InjectMocks
private Person person;
Logger logger = PowerMockito.mock(Logger.class);
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
4. 待测试类中的方法无法做代理
|