软件构造(二)

博主在进行软件构造实验时遇到了JUnit测试的迷惑行为:同一测试方法在不同类设置下导致不同方法被调用。当测试基类为抽象类时,调用了子类的方法;变为普通类时,调用了基类的方法。通过对测试结果的分析,博主推测这是由于在运行测试时,系统根据类的类型创建对象并执行测试方法。此现象引发了对JUnit内部机制的思考,并提出进一步研究源码的计划。
摘要由CSDN通过智能技术生成

软件构造实验遇到的问题

在进行学校的软件构造实验时,我遇到了一些问题,故以此方式记录下来,希望以后自己有能力解决。

JUnit的使用

在使用JUnit写测试类的时候出现了一种奇怪的现象:对于某一方法,明明写了测试方法,结果用覆盖率运行的时候却发现这个方法根本未被覆盖,即便是单独运行对应的测试方法依然显示未被覆盖。

public class MyObject {
    public MyObject() {
    }
    public void add() {
        System.out.println(2);
    }
}
public class demo {
    public demo(){
    }
    public void add(){
        System.out.println(1);
    }
}
public abstract class demoTest {
    @Test
    public void testforadd(){
        demo d= new demo();
        d.add();
    }
}
public class MyObjectTest extends demoTest{
    @Test
    public void testforadd(){
        MyObject m=new MyObject();
        m.add();
    }
}

运行demoTest之后的结果如下
在这里插入图片描述
这说明最终被调用的是MyObject中的add方法。此时我认为是由于MyObjectTest重写了demoTest中的testforadd方法,但是当我把demoTest从抽象类改为实体类之后,运行结果如下:
在这里插入图片描述
这说明最终被调用的是demo中的add方法。此时我产生疑问:以上两种情况都是MyObjectTest重写了demoTest中的testforadd方法,那为何最终调用的方法不一样呢?
仔细观察之后,我注意到在运行结果左边的不同之处:虽然我两次点击的都是demoTest的运行,但是在demoTest为抽象类时,最终运行的是MyObjectTest;在demoTest为实体类时,最终运行的是demoTest。
由此我联想到了在写功能代码时抽象类和实体类的区别:抽象类不能有构造方法;实体类可以有构造方法。也就是说,我在运行测试类的时候,相当于系统内部自动为我写好了客户端代码,这个代码会为所有测试类都建立一个对象,然后再运行这些对象中的所有测试方法。当demoTest为抽象类时,系统会用MyObjectTest来为其构造对象,因此便会使用重写后的方法;当demoTest为实体类时,系统会用demoTest来为其构造对象,因此便会使用重写前的方法。
为了佐证以上结论,我将demoTest改回抽象类,将MyObjectTest删除,运行demoTest,运行结果如下:
在这里插入图片描述
结果进一步说明我的观点是正确。
不过以上结论都是我基于现有的几个实例瞎总结,真正的原因恐怕还是得去翻阅JUnit的源码,希望我以后有能力去实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值