51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 16602|回复: 6
打印 上一主题 下一主题

用Junit测试void方法(原创)

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2005-11-3 23:00:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Junit通常用于那些有明确返回值的方法的测试,而无法对返回值是void类型的方法进行测试,因为Junit的assert断言方法只适用于预期值与实际值的比较,对于void类型的方法,我们无法从它的return语句获得具体的返回值。因此我们要使用junit测试void方法,必须找到一个有实际返回值的方法来暂时替代void方法,但此方法只作为被测void方法的入口和出口,测试程序所调用的仍旧是原void方法。为了实现这种测试方式,我们按照如下步骤进行。
第一步:增加全局变量flag。
public static int flag=0;
在被测程序中增加一个int类型的全局变量flag,这个flag最终也会随代码进入生产系统,但这并不影响生产运行。增加这个flag的作用是,用来给void方法的每个分支的结果进行赋值,我们可以给不同的分支附不同的flag值,这样,在用junit测试时,当我们给定一个输入,我们就能知道它会走哪条分支,此时的flag应该是什么值。
第二步:增加与void方法对应的verify方法,该方法返回int型的flag。
        public static int verInsertData(String id, String name, String sex)
        {
                MyCode mycode = new MyCode();
                try {
                        MyCode.insertData(id, name, sex);
                } catch (Exception e) {
                        System.out.println(e.toString());
                }
                return flag;
        }

从上面的程序可以看出,被测方法inserData被增加的verify方法verInsertData所调用,且返回值是一个int型的flag。
第三步:为被测方法设定每个分支的返回值。
        static void insertData(String person_id, String person_name, String person_sex)
                throws Exception {

                try {

                                //personid必须为正整数
                                if (person_id.equals("")||estimate(person_id)== 0) {
                                        System.out.println(
                                                "personid must be digital and bigger than 0!");
                                        flag=1;
                                        return;
                                }

                                //if (person_id == "1")
                                if (Integer.parseInt(person_id) == 1) {
                                        System.out.println(
                                                "Duplicate personid,this person has been existed! ");
                                        flag=2;
                                        return;
                                }

                                //Test whether personname is blank
                                if (person_name.equals("")) {
                                        System.out.println(
                                                "personname must be input!");
                                        flag=3;
                                        return;
                                }

                                //Test whether personsex is 'm' or 'f'
                                if (!person_sex.equals("m") && !person_sex.equals("f")) {
                                        System.out.println("Invalide input ,personsex must be 'm' or 'f'!");
                                        flag=4;
                                        return;

                                }
                                System.out.println(
                                        "' " + person_name + " ' has been added successfully");
                        flag=0;

                } catch (Exception e) {
                        System.out.println(e.getMessage().toString());
                        return;
                } finally {
                        return;
                }
        }
被测方法被分成了五个分支,每个分支对都flag标志位附了不同的值,分别是0,1,2,3,4。这样的布局显然就为后面的Junit测试代码创造了良好的条件。Junit代码在已知的输入数据下,能够很快得到预期的flag值,assert时,只需要将输入数据、预期值分别提供给asserEqual方法,Juint测试代码执行时就会自动将预期的flag与实际被测程序执行的结果进行比对,如果实际得到的flag与预期的一致,说明被测程序是正确的,反之则是错误的。
第四步:编写Junit测试代码。
package com;
import junit.framework.TestCase;

public class TestMyCode extends TestCase {

        public MyCode mycode = new MyCode();
        protected void setUp() throws Exception {
                super.setUp();
                mycode = new MyCode();
        }
        public void testInsertData1() {
                try {
                        int expectedReturn;
                        int actualReturn;
                        expectedReturn = 0; //insert成功,即预期的flag=0
                        actualReturn = MyCode.verInsertData("2", "111", "m");
                        assertEquals(
                                "UTC-MyCode-insertData-01--正确等价类:sucess",
                                expectedReturn,
                                actualReturn);

                } catch (Exception e) {
                        System.out.println(e.toString());
                }
        }
       
        public void testInsertData2() {
                try {
                        int expectedReturn;
                        int actualReturn;
                        expectedReturn = 1; //id为空,insert失败,,即预期的flag=1
                        actualReturn = MyCode.verInsertData("", "111", "m");
                        assertEquals(
                                "UTC-MyCode-insertData-02--错误等价类:fail:1",
                                expectedReturn,
                                actualReturn);

                } catch (Exception e) {
                        System.out.println(e.toString());
                }
        }
       
        public void testInsertData3() {
                try {
                        int expectedReturn;
                        int actualReturn;
                        expectedReturn = 2; //id为1,重复,insert失败,即预期的flag=2
                        actualReturn = MyCode.verInsertData("1", "222", "f");
                        assertEquals(
                                "UTC-MyCode-insertData-03--错误等价类:fail:2",
                                expectedReturn,
                                actualReturn);

                } catch (Exception e) {
                        System.out.println(e.toString());
                }
        }
       
        public void testInsertData4() {
                try {
                        int expectedReturn;
                        int actualReturn;
                        expectedReturn = 3; //name为空,insert失败,即预期的flag=3
                        actualReturn = MyCode.verInsertData("3", "", "f");
                        assertEquals(
                                "UTC-MyCode-insertData-04--错误等价类:fail:3",
                                expectedReturn,
                                actualReturn);

                } catch (Exception e) {
                        System.out.println(e.toString());
                }
        }

        public void testInsertData5() {
                try {
                        int expectedReturn;
                        int actualReturn;
                        expectedReturn = 4; //sex不是m或f,insert失败,即预期的flag=4
                        actualReturn = MyCode.verInsertData("4", "ggg", "h");
                        assertEquals(
                                "UTC-MyCode-insertData-05--错误等价类:fail:4",
                                expectedReturn,
                                actualReturn);

                } catch (Exception e) {
                        System.out.println(e.toString());
                }
        }

        protected void tearDown() throws Exception {
                mycode = null;
                super.tearDown();
        }
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

2#
发表于 2005-11-5 13:05:10 | 只看该作者
呵呵,感谢原创
回复 支持 反对

使用道具 举报

该用户从未签到

3#
发表于 2006-3-13 22:15:50 | 只看该作者
支持原创
回复 支持 反对

使用道具 举报

该用户从未签到

4#
发表于 2011-5-28 15:15:26 | 只看该作者
您好,我是单元测试初学者~
但是我觉得您的这个方法只能证明输入的数据是否合法,但是对方法是否达到了预计目的,却不能确保。
比如说,在void方法中写了一个数据库数据插入的语句,函数参数虽然检测是正确的,但是函数的效果是可能有缺陷的,比如说:数据库假如规定编码是iso8859,那么插入的中文就会在数据库里变成乱码——这一结果是这样的单元测试所无法发现的。
我觉得这样的单元测试只能测试输入数据的合法性,而不能证明函数方法的有效性。
回复 支持 反对

使用道具 举报

该用户从未签到

5#
发表于 2011-8-16 15:23:40 | 只看该作者
支持原创,但是需要说明的是,你自己创建了一个验证参数的方法,并把他归纳为你的源方法的测试方法。
在我看来先不说验证参数的方法应该在客户端还是服务器端产生,但是这个验证方法不应该是加出来的,而是应该本来就存在的,如果原来没有这个验证方法的话,说明你的源方法可以接受所有符合参数类型的数据,包括空数据,单元测试只针对源方法的内部,如果内部本身有验证,那么即使没有返回值,我们也可以通过他所插入的数据库数据,或者所改变的全局变量来判断这个方法体本身的有效性。
    你上面的代码只是测试了这个验证方法体而已。对于接口方法体的参数合法性单元测试不用考虑的,参数类型不正确本身就是异常,而非BUG。
回复 支持 反对

使用道具 举报

该用户从未签到

6#
发表于 2011-9-26 16:35:13 | 只看该作者
mark
回复 支持 反对

使用道具 举报

该用户从未签到

7#
发表于 2012-2-24 10:16:05 | 只看该作者
以前也为这个事情困惑过,现在终于豁然开朗,谢谢了。
回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-4-19 16:51 , Processed in 0.076236 second(s), 26 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表