JUnit单元测试(断言、生命周期)
单元测试一、概念与意义1、概念单元测试就是针对最小的功能单元编写测试代码。Java程序最小的功能单元是方法,因此对Java程序进行单元测试就是针对单个Java方法的测试。2、意义使用main方法进行测试有很多缺点,一是一个类中只能有一个main方法,不能把测试代码分离,二是没有打印出测试结果和期望结果,例如,expected:362800,but actual:123456,三是很难编写一组通
单元测试
一、概念与意义
1、概念
单元测试就是针对最小的功能单元编写测试代码。Java程序最小的功能单元是方法,因此对Java程序进行单元测试就是针对单个Java方法的测试。
2、意义
使用main方法进行测试有很多缺点,一是一个类中只能有一个main方法,不能把测试代码分离,二是没有打印出测试结果和期望结果,例如,expected:362800,but actual:123456,三是很难编写一组通用的测试代码。因此我们需要一种测试框架,帮助我们编写测试。
二、JUnit
1、用途与意义
JUnit是一个开源的Java语言的单元测试框架,使用最广泛。使用JUnit的好处在于,我们可以非常简单地组织测试代码,还可以统计测试的代码覆盖率,即被测试的代码本身有多少经过了测试。
2、使用
以Eclipse为例,当我们已经编写了一个testUserDaoImpl.java`文件后,我们想对其进行测试,需要编写一个对应的testUserDaoImplTest.java文件,以Test为后缀是一个惯例,并分别将其放入src和test目录中。最后,在Project-Properties-Java Build Path-Libraries中添加JUnit 4的库:
整个项目结构如下:

我们来看一下``testUserDaoImplTest.java`的内容:
代码中注解包括@BeforeClass(所有测试方法前执行)、@AfterClass(所有测试方法结束后执行)、@Before(测试方法前执行)、@After(测试方法后执行)、@Test(测试方法)。
package test;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import dao.impl.UserDaoImpl;
import entity.User;
public class UserDaoImplTest {
UserDaoImpl udi=new UserDaoImpl();
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testLoginUser() {
String userName="bbsn";
String passWord="02200059";
User u=udi.loginUser(userName, passWord);
assertNotNull(u);
}
}
核心测试方法testUserDaoImplTest()加上了@Test注解,这是JUnit要求的,它会把带有@Test的方法识别为测试方法。在测试方法内部,我们用assertNotNull(u)表示,期望udi.loginUser(userName, passWord)返回非空。Assertion还定义了其他断言方法,例如:
assertTrue(): 期待结果为trueassertFalse(): 期待结果为falseassertNotNull(): 期待结果为非nullassertArrayEquals(): 期待结果为数组并与期望数组每个元素的值均相等- …
运行单元测试非常简单。选中``testUserDaoImplTest.java文件,点击Run-Run As-JUnit Test`,Eclipse会自动运行这个JUnit测试,并显示结果:

如果测试结果与预期不符,assertNotNull()会抛出异常,我们就会得到一个测试失败的结果:

在Failure Trace中,JUnit会告诉我们详细的错误结果:

3、断言
我们可以使用断言(Assertion)来测试期望结果,可以方便地组织和运行测试,并查看结果。
(1)assertEquals断言
这是应用非常广泛的一个断言,它的作用是比较实际的值和用户预期的值是否一样,assertEquals在JUnit中有很多不同的实现,以参数expected和actual都为Object类型的为例,assertEquals定义为:
static public void assertEquals(String message, Object expected, Object actual) {
if (expected== null&& actual == null)
return;
if (expected != null&& expected.equals(actual))
return;
failNotEquals(message, expected, actual);
}
其中,expected为用户期望某一时刻对象的值,actual为某一时刻对象实际的值。如果这两值相等的话(通过对象的equals方法比较),说明预期是正确的,也就是说,代码运行是正确的。assertEquals还提供了其它的一些实现,例如整数比较,浮点数的比较等等。
(2)assertTrue与assertFalse断言
assertTrue与assertFalse可以判断某个条件是真还是假,如果和预期的值相同则测试成功,否则将失败,assertTrue的定义如下:
staticpublic void assertTrue(String message, boolean condition) {
if (!condition)
fail(message);
}
“condition”表示要测试的状态,如果“condition”的值为false,则测试将会失败。
(3)assertNull与assertNotNull断言
assertNull与assertNotNull可以验证所测试的对象是否为空或不为空,如果和预期的相同则测试成功,否则测试失败,assertNull定义为:
staticpublic void assertNull(String message, Objectobject) {
assertTrue(message,object == null);
}
其中,object就是要测试的对对象,如果object为空,该测试成功,否则失败,是不是很简单。
(4)assertSame与assertNotSame断言
assertSame和assertEquals不同,assertSame测试预期的值和实际的值是否为同一个参数(即判断是否为相同的引用)。assertNotSame则测试预期的值和实际的值是不为同一个参数。assertSame的定义为:
static publicvoid assertSame(String message, Object expected, Object actual) {
if (expected== actual)
return;
failNotSame(message, expected, actual);
}
而assertEquals则判断两个值是否相等,通过对象的equals方法比较,可以相同引用的对象,也可以不同。
(5)fail断言
“fail”断言能使测试立即失败,这种断言通常用于标记某个不应该被到达的分支。例如assertTrue断言中,condition为false时就是正常情况下不应该出现的,所以测试将立即失败,fail的定义为:
staticpublic void fail(String message) {
throw new AssertionFailedError(message);
}
当一个失败或者错误出现的时候,当前测试方法的执行流程将会被中止,但是位于同一个测试类中的其他测试将会继续运行。
三、规范
在编写单元测试的时候,我们要遵循一定的规范:
一是单元测试代码本身必须非常简单,能一下看明白,决不能再为测试代码编写测试;
二是每个单元测试应当互相独立,不依赖运行的顺序;
三是测试时不但要覆盖常用测试用例,还要特别注意测试边界条件,例如输入为0,null,空字符串""等情况。
更多推荐



所有评论(0)