JUnit提供了一些辅助函数,用于帮助你确定某个被测试函数是否工作正常。通常而言,我们把所有这些函数统称为断言。它让你可以确定:某条件是否为真;两个数据是否相等,或不等,或者其他的一些情况。下面逐个介绍JUnit提供的每一个断言(assert)方法。
assertEquals(String message, double expected, double actual, double delta)
这是使用得最多的断言形式。上面的参数中,expected是你的期望值,actual是被测试代码实际产生的值,message是一个可选的消息,如果提供的话,将会在发生错误的时候报告这个消息。delta表示精确度。
assertEquals("Should be 3 1/3",3.33,10.0/3.0,0.01)
assertNull
assertNull(String message, Object object)
assertNotNull(String message, Object object)
验证一个给定的对象是否为null(或者为非null),如果答案为否,则将会失败。message参数是可选的。
assertTrue
assertTrue(String message, boolean condition)
验证给定的二无条件是否为真,如果为假的话,将会失败。message参数是可选的。
这种写法被用于确认某个分支,或者异常逻辑才有可能是正确的选择。
assertFalse(String message, boolean condition)
验证给定的二无条件是否为假,如果为真的话,将会失败。message参数是可选的。
assertSame
assertSame(String message, Object expected, Object actual)
验证expected参数和actual参数所引用的是否为同一个对象,如果不同的话,将会失败。message参数是可选的。
assertNotSame(String message, Object expected, Object actual)
验证expected参数和actual参数所引用的是否为同一个对象,如果相同的话,将会失败。message参数是可选的。
fail
fail(String message)
上面的断言将会使测试立即失败,其中message参数是可选的。这种断言通常被用于标记某个不应该被到达的分支(例如,在一个预期发生的异常之后)。
JUnit测试骨架:
用JUnit写测试真正所需要的就三件事:
1、一个import语句引入所有JUnit.framework.*下的类。
2、一个extends语句让你的类从TestCase继承。
3、一个调用Super(string)的构造函数。
许多IDE至少会提供这些给你,这样写出来的类能够使用JUnit的test runner运行,并且自动执行类中所有的...test方法。
import junit.framework.TestCase;
public class AddtionTest extends TestCase {
public AddtionTest(String name) {
super(name);
}
public void testAdd() {
this.assertEquals(2, 1 + 1);
}
}
定义一个类,每个包含测试的类都必须如所示那样由TestCase继承而来。基类TestCase提供了我们所需的大部分单元测试功能,包括所有在前面讲述过的断言方法。
基类需要一个以String为参数的构造函数,因而我们必须调用super以传递这么一个名字。我们不知道这个名字此时是什么,因而我们就仅仅让我们自己的构造函数接受String参数并把这个参数在第五行传递上去。
最后,测试类包含了名为XXtest的方法。
JUnit测试组成
一个测试类包含一些测试方法;每个方法包含一个或者多个断言语句。但是测试类也能调用其他测试类:单独的类,包,甚至完整的一个系统。这可能通过创建test suite来取得。任何测试类都能包含一个名为suite的静态方法:
public static Test suite();
你可以提供suite()方法来返回任何你想要的测试集合(没有suite()方法,JUnit会自动运行所有的...test方法)。但是你可能需要手工添加特殊的测试,包括其他suite。
假设有如下的测试类:
所以我们必须显示的说明要运行哪个方法。当我们调用test suite的时候,只有那些运行不花多少时间的测试会补运行。而且,此时我们看到了给构造函数的string参数是做什么用的了:它让TestCase返回了一个对命名测试方法的引用。这儿,我们使用它来得到那两个耗时少的方法的引用,它把它们包含到test suite之中。
然后我们再用一个高一级别的测试来组合这两个测试类:
运行TestClassComposite,以下单个的测试方法都将被运行:
TestClassOne的testAddition()
TestClassOne的testSubtraction()
TestClassTwo的testShortTest()
TestClassTwo的testAnotherShortTest()
每个测试的运行都应该是相互独立的;从而你就可以在任何时候,以任意的顺序运行每个单独的测试。
在调用每个xxtest方法之前,调用方法setup();并且在每个测试方法完成之后,调用方法tearDown()。假设对于每个测试,你都需要某种数据库连接。这时,你就需要在每个测试方法中重复建立连接和释放连接了,而只须在setup和teardown方法中分别建立和释放连接:public class TestDB extends TestCase {
public TestDB(String name) {
super(name);
}
protected void setUp() throws Exception {
dbconn = new Connection("Oracle", "1521", "fred", "foobar");
dbconn.connect();
}
protected void tearDown() throws Exception {
dbconn.disConnect();
dbconn = null;
}
public void testAccount() {
// use dbconn
}
public void testEmployee() {
// use dbconn
}
}
在上例中,在调用tessAccount()之前,将会先调用setup();然后在tessAccount()之后,会接着调用tearDown()。在第二个测试函数testEmployee()中,也是按顺序先调用setup(),再调用该函数,最后调用tearDown()。
protected void setUp()
protected void tearDown()