首页 > 代码库 > Junit(转自http://blog.csdn.net/yueweiac110/article/details/5376476)

Junit(转自http://blog.csdn.net/yueweiac110/article/details/5376476)

8.3  JUnit的使用方法

JUnit的使用非常简单,共有3步:第一步、编写测试类,使其继承TestCase;第 二步、编写测试方法,使用test+×××的方式来命名测试方法;第三步、编写断言。如果测试方法有公用的变量等需要初始化和销毁,则可以使用 setUp,tearDown方法。

8.3.1  继承TestCase

如果要使用JUnit,则测试类都必须继承TestCase。当然目前的最新版JUnit 是不需要继承它的,但并不是说TestCase类就没有用了,它仍然是JUnit工作的基础。这里先讲述继承TestCase类的方式,稍后再介绍不继承 的方式。

下面是前面使用JUnit进行测试 AddAndSub类的代码,这里进行详细的分析:

//******* TestAddAndSub.java**************

import junit.framework.TestCase;

public Class TestAddAndSub  extends TestCase {

    public void testadd() {

        //断言计算结果与10是否相等

        assertEquals(10, AddAndSub.add(4, 6));

    }

    public void testsub() {

        //断言计算结果与2是否相等

        assertEquals(2, AddAndSub.sub(6, 4));

    }

    public static void main(String args[]){ 

         junit.textui.TestRunner.run(TestAddAndSub .class);    }

}

代码说明:

— 这里继承TestCase,表示该类是一个测试类。

— 然后使用junit.textui.TestRunner.run方法来执行这个测试类。

这里给出TestCase的源代码:

//******* TestCase.java**************

package junit.framework;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.lang.reflect.Modifier;

public abstract class TestCase extends Assert implements Test {

    /**测试案例的名称*/

    private String fName;

    /**构造函数

     */

    public TestCase() {

        fName= null;

    }

    /**带参数的构造函数

     */

    public TestCase(String name) {

        fName= name;

    }

    /**获取被run执行的测试案例的数量

     */

    public int countTestCases() {

        return 1;

    }

    /**创建一个TestResult

     * @see TestResult

     */

    protected TestResult createResult() {

        return new TestResult();

    }

    /**执行run方法,返回TestResult

     * @see TestResult

     */

    public TestResult run() {

        TestResult result= createResult();

圆角矩形: 下面一段代码描述了JUnit如何实现在执行具体的测试方法前,先执行初始化方法,在执行完具体的测试方法后,再执行销毁方法。         run(result);

        return result;

    }

    /**执行run方法,参数为TestResult

     */

    public void run(TestResult result) {

        result.run(this);

    }

    /**执行测试方法,包括初始化和销毁方法

     * @throws Throwable if any exception is thrown

     */

    public void runBare() throws Throwable {

        Throwable exception= null;

        setUp();

        try {

            runTest();

        } catch (Throwable running) {

            exception= running;

        }

        finally {

            try {

                tearDown();

            } catch (Throwable tearingDown) {

                if (exception == null) exception= tearingDown;

            }

        }

        if (exception != null) throw exception;

    }

    /**执行测试方法

     * @throws Throwable if any exception is thrown

     */

    protected void runTest() throws Throwable {

        assertNotNull("TestCase.fName cannot be null", fName); // Some VMs crash when calling getMethod(null,null);

        Method runMethod= null;

        try {

            //利用反射机制

            runMethod= getClass().getMethod(fName, (Class[])null);

        } catch (NoSuchMethodException e) {

            fail("Method """+fName+""" not found");

        }

        if (!Modifier.isPublic(runMethod.getModifiers())) {

            fail("Method """+fName+""" should be public");

        }

         //利用反射机制

        try {

            runMethod.invoke(this);

        }

        catch (InvocationTargetException e) {

            e.fillInStackTrace();

            throw e.getTargetException();

圆角矩形: 下面一段代码定义了要想实现初始化和销毁方法,需继承这两个方法。         }

        catch (IllegalAccessException e) {

            e.fillInStackTrace();

            throw e;

        }

    }

    /**测试前的初始化方法

     */

    protected void setUp() throws Exception {

    }

    /**测试后的销毁方法

     */

    protected void tearDown() throws Exception {

    }

    /**返回测试案例的名称

     * @return the name of the TestCase

     */

    public String getName() {

        return fName;

    }

    /**设定测试案例的名称

     * @param name the name to set

     */

    public void setName(String name) {

        fName= name;

    }

}

代码说明:

— 该类继承了Assert 类,实现了Test接口。

— 可以看出,TestCase类正是通过runBare实现了在测试方法前初始化相关变量和环境,在测试方法后销毁相关变量和环境。

8.3.2  编写测试方法

测试方法名要以test+方法名来命名,当 然最新版的JUnit支持直接以方法名来命名测试方法。这是通过TestCase类里的runTest方法来实现的,主要利用了Java的反射机 制,runTest方法的代码如下:

protected void runTest() throws Throwable {

        assertNotNull("TestCase.fName cannot be null", fName); // Some VMs crash when calling getMethod(null,null);

        Method runMethod= null;

        try {

            // 获取要测试的方法

            runMethod= getClass().getMethod(fName, (Class[])null);

        } catch (NoSuchMethodException e) {

            fail("Method """+fName+""" not found");

        }

        //判断要测试的方法是否为公用方法

        if (!Modifier.isPublic(runMethod.getModifiers())) {

            fail("Method """+fName+""" should be public");

        }

         //Java的反射机制

        try {

            runMethod.invoke(this);

        }

         //抛出调用异常

        catch (InvocationTargetException e) {

            e.fillInStackTrace();

            throw e.getTargetException();

        }

        catch (IllegalAccessException e) {

            e.fillInStackTrace();

            throw e;

        }

    }

8.3.3  编写断言

JUnit主要有以下断言:

—  assertEquals(期望值,实际值),检查两个值是否相等。

—  assertEquals(期望对象,实际对象),检查两个对象是否相等,利用对象的equals()方法进行判断。

—  assertSame(期望对象,实际对象),检查具有相同内存地址的两个对象是否相等,利用内存地址进行判断,注意和上面assertEquals方法 的区别。

—  assertNotSame(期望对象,实际对象),检查两个对象是否不相等。

—  assertNull(对象1,对象2),检查一个对象是否为空。

—  assertNotNull(对象1,对象2),检查一个对象是否不为空。

—  assertTrue(布尔条件),检查布尔条件是否为真。

—  assertFalse(布尔条件),检查布尔条件是否为假。

这些断言主要定义在JUnit的 Assert类里,Assert类的示例代码如下:

//******* Assert.java**************

package junit.framework;

/**一系列的断言方法

 */

public class Assert {

    /**构造函数

     */

    protected Assert() {

    }

    /**断言是否为真,带消息

     */

    static public void assertTrue(String message, boolean condition) {

        if (!condition)

            fail(message);

    }

    /**断言是否为真

     */

    static public void assertTrue(boolean condition) {

        assertTrue(null, condition);

    }

    /**断言是否为假,带消息

     */

    static public void assertFalse(String message, boolean condition) {

        assertTrue(message, !condition);

    }

    /**断言是否为假

     */

    static public void assertFalse(boolean condition) {

        assertFalse(null, condition);

    }

圆角矩形: 下面一段代码描述了如何在JUnit中实现判断是否相等的方法,这些方法要实现的内容相同,只是参数不同,从而实现了可以针对不同类型的数据来判断是否相等的功能。     /**断言是否为失败

     */

    static public void fail(String message) {

        throw new AssertionFailedError(message);

    }

    /**断言是否为失败

     */

    static public void fail() {

        fail(null);

    }

    /**是否相等的断言,带消息Object

     */

    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);

    }

    /**是否相等的断言,Object

     */

    static public void assertEquals(Object expected, Object actual) {

        assertEquals(null, expected, actual);

    }

    /**是否相等的断言,带消息String

     */

    static public void assertEquals(String message, String expected, String actual) {

        if (expected == null && actual == null)

            return;

        if (expected != null && expected.equals(actual))

            return;

        throw new ComparisonFailure(message, expected, actual);

    }

    /**是否相等的断言,String

     */

    static public void assertEquals(String expected, String actual) {

        assertEquals(null, expected, actual);

    }

    /**是否相等的断言,带消息double

     */

    static public void assertEquals(String message, double expected, double actual, double delta) {

        if (Double.compare(expected, actual) == 0)

            return;

        if (!(Math.abs(expected-actual) <= delta))

            failNotEquals(message, new Double(expected), new Double(actual));

    }

    /**是否相等的断言,double

     */

    static public void assertEquals(double expected, double actual, double delta) {

        assertEquals(null, expected, actual, delta);

    }

    /**是否相等的断言,带消息float

     */

    static public void assertEquals(String message, float expected, float actual, float delta) {

        if (Float.compare(expected, actual) == 0)

            return;

        if (!(Math.abs(expected - actual) <= delta))

                failNotEquals(message, new Float(expected), new Float(actual));

    }

    /**是否相等的断言, float

     */

    static public void assertEquals(float expected, float actual, float delta) {

        assertEquals(null, expected, actual, delta);

    }

    /**是否相等的断言,带消息long

     */

    static public void assertEquals(String message, long expected, long actual) {

        assertEquals(message, new Long(expected), new Long(actual));

    }

    /**是否相等的断言, long

     */

    static public void assertEquals(long expected, long actual) {

        assertEquals(null, expected, actual);

    }

    /**是否相等的断言,带消息boolean

     */

    static public void assertEquals(String message, boolean expected, boolean actual) {

         assertEquals(message, Boolean.valueOf(expected), Boolean.valueOf(actual));

     }

    /**是否相等的断言,boolean

     */

    static public void assertEquals(boolean expected, boolean actual) {

        assertEquals(null, expected, actual);

    }

    /**是否相等的断言,带消息byte

     */

     static public void assertEquals(String message, byte expected, byte actual) {

        assertEquals(message, new Byte(expected), new Byte(actual));

    }

    /**是否相等的断言, byte

     */

    static public void assertEquals(byte expected, byte actual) {

        assertEquals(null, expected, actual);

    }

    /**是否相等的断言,带消息char

     */

     static public void assertEquals(String message, char expected, char actual) {

         assertEquals(message, new Character(expected), new Character(actual));

     }

    /**是否相等的断言,char

     */

     static public void assertEquals(char expected, char actual) {

        assertEquals(null, expected, actual);

    }

    /**是否相等的断言,带消息short

     */

    static public void assertEquals(String message, short expected, short actual) {

         assertEquals(message, new Short(expected), new Short(actual));

    }

     /**是否相等的断言,short

    static public void assertEquals(short expected, short actual) {

        assertEquals(null, expected, actual);

    }

    /**是否相等的断言,带消息int

     */

     static public void assertEquals(String message, int expected, int actual) {

        assertEquals(message, new Integer(expected), new Integer(actual));

     }

     /**是否相等的断言,int

     */

     static public void assertEquals(int expected, int actual) {

         assertEquals(null, expected, actual);

    }

圆角矩形: 下面一段代码描述了JUnit中如何实现判断是否为null的方法,这些方法的功能相同,只是一个带消息,一个不带消息。     /**是否不为null的断言 Object

     */

    static public void assertNotNull(Object object) {

        assertNotNull(null, object);

    }

    /**是否不为null的断言,带消息Object

     */

    static public void assertNotNull(String message, Object object) {

        assertTrue(message, object != null);

    }

    /**是否为null的断言Object

     */

圆角矩形: 下面一段代码描述了JUnit中如何实现判断是否相同的方法,这些方法要实现的内容相同,只是参数不同。     static public void assertNull(Object object) {

        assertNull(null, object);

    }

    /**是否为null的断言,带消息Object

     */

    static public void assertNull(String message, Object object) {

        assertTrue(message, object == null);

    }

    /**是否相同的断言,带消息*/

    static public void assertSame(String message, Object expected, Object actual) {

        if (expected == actual)

            return;

        failNotSame(message, expected, actual);

    }

    /**是否相同的断言,Object

     */

    static public void assertSame(Object expected, Object actual) {

        assertSame(null, expected, actual);

    }

    /**是否不相同的断言,带消息

     */

    static public void assertNotSame(String message, Object expected, Object actual) {

        if (expected == actual)

            failSame(message);

    }

    /**是否不相同的断言Object

     */

    static public void assertNotSame(Object expected, Object actual) {

        assertNotSame(null, expected, actual);

    }

    /**相同时失败

     */

    static public void failSame(String message) {

        String formatted= "";

        if (message != null)

            formatted= message+" ";

        fail(formatted+"expected not same");

    }

    /**不相同时失败

     */

    static public void failNotSame(String message, Object expected, Object actual) {

        String formatted= "";

        if (message != null)

            formatted= message+" ";

        fail(formatted+"expected same:<"+expected+"> was not:<"+actual+">");

    }

    /**不相等时失败

     */

    static public void failNotEquals(String message, Object expected, Object actual) {

        fail(format(message, expected, actual));

    }

    /**格式化消息

     */

    public static String format(String message, Object expected, Object actual) {

        String formatted= "";

        if (message != null)

            formatted= message+" ";

        return formatted+"expected:<"+expected+"> but was:<"+actual+">";

    }

}

从上述代码中,读者可以研读JUnit中有关断言 的实现方式,其实,最终都是使用后面的几个static方法来实现的。

Junit(转自http://blog.csdn.net/yueweiac110/article/details/5376476)