1 简介
对编码完成的功能,进行测试,是每个程序员最熟悉不过的事了,每完成一部分功能,都需要对实现的功能进行测试,然后才能进行交付。但如何保证自己完成的每个功能都是正确无误的呢?对,单元测试!
2 JUnit
2.1 pom 中增加 Junit 的 jar 的依赖
< dependency >
< groupId > junit </ groupId >
< artifactId > junit </ artifactId >
< version > 4.8.2 </ version >
</ dependency >
2.2 增加单元测试类
例如,要测试的类为 src 下的 com.runqianapp.userManager.dao.UserDao 类中的
public String getUserName(String userId) 方法
则首先新建一个 test 的源码目录,原因是测试代码要与原功能代码分离,自动构建的时候,只需要把原功能的代码构建到最新的 jar 里。然后新建跟被测试类相同的包路径,如
test 下的 com.runqianapp.userManager.dao.UserDaoTest
这样,就为 UserDao 建好了一个单元测试类,
对于被测试的方法,需要传不同的参数,来检验方法的正确性,这个时候,不必写多个 @Test 来测试,而是把需要传入的参数放入配置文件,然后读配置文件。
参数配置文件的位置是与单元测试类同一目录下,如
test 下 com.runqianapp.userManager.dao.testData_UserDao
2.3 JUnit 的常用注解介绍
2.3.1 @Test
需要运行的单元测试方法,可以有多个
2.3.2 @Before
在每一个 @Test 方法运行之前都会被运行,可以用来初始化方法
2.3.3 @Before
在每一个 @Test 方法运行之后都会被运行,可以用来方法的释放资源
2.3.4 @BeforeClass
针对整个单元测试类,只会被运行一次,在所有方法运行之前被运行,可以用来初始化环境
必须声明成 static void
2.3.5 @AfterClass
针对整个单元测试类,只会被运行一次,在所有方法运行之后被运行,可以用来释放资源
必须声明成 static void
2.4 断言
对于需要测试的方法,用断言来判断其它执行结果是否正确。
assertEquals([Stringmessage],expected,actual)
message 是个可选的消息,将会在发生错误时报告这个消息。
expected 是期望值,通常都是用户指定的内容。
actual 是被测试的代码返回的实际值。
如:
boolean success = update();
assertEquals(“ 更新是否成功 ”,true,success)
这样,当运行 update() 的返回值不为 true 的时候,这个单元测试就会失败。
但有些时候,我们测试的方法并没有返回值,方法只是执行一个动作,那么这个时候,我们就不能用判断的返回值来判断方法是否执行成功。
如新建文件的方法, public void createFile(String filePath) ,这个时候,方法并没有返回值,我们在判断方法是否执行成功的时候,可以写一个辅助方法,来检查一下指定的文件是否新建成功了,以此来验证 createFile() 的准备性。如:
createFile(“d:/a.txt”);
boolean exist = fileExist(“d:/a.txt”);
assertEquals(“ 新建文件 ”,true, exist);
3 JMockit
当我们在编写单元测试的时候,常常会出现一些如调用的方法需要其它对象提供,而这个类现在又不具备,如很难创建、没有环境、没有开发完等情况,这个时候,我们就需要用 JMockit 模拟出一个类,来满足我们的需求,来完成我们核心功能的测试。
3.1 pom 中增加 JMockit 的依赖
< dependency >
< groupId > jmockit </ groupId >
< artifactId > jmockit </ artifactId >
< version > 1.0 </ version >
< scope > test </ scope >
</ dependency >
3.2 模拟对象
如需要测试的一个方法的一个值是配置在 misInitConfig.xml 中的,而 misInitConfig.xml 中的值需要用 ReadConfInfo.getPropery() 来获取,而 ReadConfInfo 是在应用启动时初始化的,这个时候并没有 web 环境,也不能初始化,而我们也不需要自己手动初始化 ReadConfInfo ,因为我们测试的重点不是 ReadConfInfo ,而是我们现有的功能。这个时候,我们就可以用 JMockit 模块出 ReadConfInfo ,来完成此功能的测试。
/**
* 模拟 ReadConfInfo
*/
publicstatic void mockReadConfInfo() {
newMockUp<ReadConfInfo>() {
@Mock
publicString getPropery(String propertyName) {
if("conf_loglevel".equals(propertyName)) {
return"debug";
}else if ("conf_logfolder".equals(propertyName)) {
return"log";
}else {
return"";
}
}
};
}
在单元测试的 @BeforCalss 中初始化,
/**
* 初始化环境
*/
@BeforeClass
publicstatic void init() throws Exception {
// 模拟 ReadConfInfo
mockReadConfInfo();
}
这样,我们就可以在程序中使用 ReadConfInfo.getPropery() 来完成我们的功能了。