繁体   English   中英

为工厂方法创建单元测试

[英]Create unit tests for a factory method

我正在遵循一个较旧的Java教程,该教程讲授Service层的概念,我的程序是一个非常简单的程序,它将创建一个Bills及其到期日的列表。 我遇到的困难是为工厂方法创建JUnit测试。

首先是条例草案的建设者

public Bill(String bname, Double bamount, Date bdate, String bfrequency){
 this.billName = bname;
 this.billAmount = bamount;
 this.billDueDate = bdate;
 this.frequency = bfrequency;
}

接下来是保存和获取这些账单的界面

public interface IBill {
    public void save(Bill bill);
    public Bill read(Bill readbill);


}

请耐心等待,接下来是暂时取消的接口的具体实现,尚未实现

public class BillSvcImpl implements IBill {

    @Override
    public void save(Bill bill) {
        System.out.println("Entering the Store BillInfo method");

    }

    @Override
    public Bill read(Bill readbill) {
        System.out.println("Entering the Read BillInfo method");
        return null;
    }

}

然后有一个工厂方法将创建/调用具体实现

public class Factory {

    public IBill getBillInfo(){
        return new BillSvcImpl();
    }

}

然后最后是我卡住的JUnit测试

    public class BillSvcTest extends TestCase {
    private Factory factory;

    @Before
    public void setUp() throws Exception {
        super.setUp();
        factory = new Factory();

    }
    @test
    public void testSaveBill(){
        IBill bill = factory.getBillInfo();
        Bill nanny = new Bill("Nanny",128d,new Date(6/28/2013),"Montly");
        bill.save(nanny);
        //what goes here??, Assert??

    }

    @test
    public void testReadBill(){
    //How can I write a Test for this??
        //Please help
    }

}

指令是

为您的服务创建一个JUnit测试。该测试应使用Factory获取服务,该服务在setUp()方法中实例化。

我的服务/接口有两种保存和获取方法,如何在开始实际实现之前为它们创建测试。

任何帮助表示赞赏。 谢谢

首先, 不要扩展TestCase而是使用JUnit4.x。

其次,我强烈反对带有副作用的方法。 没有理由修改您的save方法以返回boolean而不是void 您只需要采用另一种方法来测试该方法。

第三,我认为,简单的单元测试无法涵盖此方法的保存功能。 看起来像可以持久保存的东西更适合某种集成测试(使用数据库,确保文件存在并且内容正确,等等)。

在进行单元测试时,您要回答的主要问题是:“给定此参数,此方法调用的预期结果是什么?” 当我们调用save ,我们期望发生什么? 我们是否写入数据库? 我们是否序列化内容并写入文件? 我们是否将XML / JSON /纯文本写出来? 首先必须回答这个问题, 然后才能围绕它编写一个有用的测试。

read同样的事情-当我尝试阅读账单时,我期望得到什么作为输入? 传递一个Bill对象,然后返回一个Bill对象,我会得到什么? (为什么外线呼叫者会有我要阅读的账单的概念?)

您必须充实对这些方法的期望。 这是我用来编写单元测试的一种方法:

  • 给定特定的输入,
  • 我调用此方法时
  • 那么我希望这些事情是真的。

您必须先定义期望,然后才能编写单元测试。

IMO的save方法应该返回一些信息来说明Bill是否被保存。 我会保留这样的保存方法

public boolean save(Bill bill) {
    System.out.println("Entering the Store BillInfo method");
    boolean result = false;
    try {
       //..... saving logic
       result = true;
    }
    catch(Exception e) {
        result = false;
        e.printStackTrace();
    }
    return result;
}

并在测试用例中声明为

@Test
public void testSaveBill(){
    //Success
    IBill bill = factory.getBillInfo();
    Bill nanny = new Bill("Nanny",128d,new Date(6/28/2013),"Montly");
    assertTrue(bill.save(nanny));

   //Failure
   assertFalse(bill.save(null));
}

通常,read()和store()的实现涉及与外部系统(如数据库,文件系统)的集成。 这使测试与外部系统齐头并进。

@Test
public void insertsBillToDatabase() {
    //setup your database

    bill.store(aBill);

    //fetch the inserted bill then assert
}

这些测试重点在于您的组件是否在外部系统上进行了正确的摘要。

取决于外部系统的测试非常昂贵,因为它们相对较慢并且难以设置/清除。 如果store()中存在一些复杂的业务逻辑,则最好将业务问题和集成问题分开。

public void store(Bill bill) {
    //business logic
    billDao.save(bill); // delegate to an injected dao, you can replace it with a test double in test code
}

@Test
public void doesSthToBillBeforeSave() {
    //replace your billDao with a stub or mock

    bill.store(aBill);

    //assert the billDao stub / mock are correctly invoked
    //assert bill's state
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM