1.单元测试(Unit Test)
单元测试(Unit Test)是一种对隔离的小型代码单元进行测试的测试实践。
单元:在Java中,一般情况下,单元就是方法。特殊地,根据业务情况,可以把一个类或者一个应用看做单元。
小型:小型代码块的用意更加明确,测试编写更加容易,易覆盖全;小型代码块所提供的反馈环路较短,测试速度更快。
隔离:对于单元中的外部依赖(如网络、文件等),应该用模拟来完成依赖所要完成的内容,保证整个测试都在内存中完成。
2.编写规范
2.1 测试类命名
测试类应都存放在src/test/java目录下,与源码目录隔离。测试类包名最好与源码相对应,创建测试类名需在源码类后加后缀Test,例源文件名称是HealthController,测试类名需要起名HealthControllerTest
2.2 测试方法命名
每个测试方法都需要在源文件方法的基本上,加前缀test,例源文件中方法是readFile,测试方法名称是readFileTest
2.3 测试资源
测试资源文件都需要存放在src/test/resources目录下,配置文件独立配置一套作为测试所用,和源码资源文件隔离开,最好不要引用源资源文件
3.测试工具
junit jmock等
4.jmock使用
4.1 jmock作用
当对A功能进行测试时,A功能中需要调用B功能,比如网络请求,数据库请求,我们可以利用jmock指定B功能输出一个想要的答案,从而测试A功能是否正确。
比如在下面的例子中,verifyTest方法中需要调用kgEntityLinkingService的getKGEntityLinking方法,而这个方法需要请求其他模块,利用jmock,生成一个代理类,指定我们需要的答案,完成对verifyTest逻辑的测试。
public class HealthControllerTest {
public HealthController healthController = new HealthController();
public final String filePath = "/Users/yangsihao/java_project/entitylink3/entitylink-service/src/test/Resources/caseTest.txt";
HashMap<String, HashMap<String, KGEntityResult>> expectMap = new HashMap<>();
KGEntityResult kgEntityResult;
@Before
public void before(){
String requestInfo = "{\"source\":1,\"searchCityId\":1,\"originKeyword\":\"天安门\"}";
String text = "天安门";
List<Integer> termIndexs = new ArrayList<>();
termIndexs.add(0);
List<KGEntity > entityInfos = new ArrayList<>();
KGEntity kgEntity = new KGEntity();
kgEntity.setEntityID("1008937214073122885");
kgEntity.setEntityType(7);
kgEntity.setEntityName("天安门广场");
kgEntity.setDpBusinessID("2017738");
kgEntity.setMtBusinessID("276514");
entityInfos.add(kgEntity);
kgEntityResult = new KGEntityResult(text, termIndexs, entityInfos);
HashMap<String, KGEntityResult> map = new HashMap<String, KGEntityResult>(){{
put(kgEntityResult.getText(), kgEntityResult);
}};
expectMap.put(requestInfo, map);
}
@Test
public void readFileTest(){
HashMap<String, HashMap<String, KGEntityResult>> fileMap = new HashMap<>();
healthController.readFile(filePath, fileMap, new StringBuilder());
Assert.assertEquals(expectMap, fileMap);
}
@Test
public void verifyTest() {
Mockery mockery = new Mockery();
//利用mockery通过反射获取代理对象
KGEntityLinking.Iface kgEntityLinkingService = (KGEntityLinking.Iface) mockery.mock(KGEntityLinking.Iface.class);
healthController.setKgEntityLinkingService(kgEntityLinkingService);
HashMap<String, HashMap<String, KGEntityResult>> fileMap = new HashMap<>();
healthController.readFile(filePath, fileMap, new StringBuilder());
List<List<KGEntityResult>> list = new ArrayList<>();
List<KGEntityResult> list1 = new ArrayList<>();
list1.add(kgEntityResult);
list.add(list1);
RequestInfo requestInfo = new RequestInfo(1, 1, "天安门");
mockery.checking(new Expectations(){
{
try {
oneOf(kgEntityLinkingService).getKGEntityLinking(requestInfo);
} catch (TException e) {
e.printStackTrace();
}
will(returnValue(list)); //设置方法的期望输出
}
});
//verify method
boolean check = healthController.verify(fileMap, new StringBuilder());
//junit Assert
Assert.assertTrue("health test false", check);
}
}
例子: