如何使用DB为方法创建jUnit测试用例

时间:2015-09-29 07:22:01

标签: java unit-testing junit mockito

我从未做过jUnit测试用例。我查找了该怎么做,但我刚刚使用assertEquals()完成了基础测试用例。 我不知道如何做这个方法:

public class Apc7Engine extends BaseEngine {

/**
 * This method retrieve plannings 
 * in APC7 configuration
 * 
 * It is an implementation of an abstract method
 * from BaseEngine.java
 *
 */
@Override
public void retrievePlannings() {
    LogCvaultImport.code(200).debug("A7: start retrievePlannings");
    try {
        List importList = DummyApc7DAOFactory.getDAO().getDummyApc7();
        Iterator poIterator = importList.iterator();

        while(poIterator.hasNext()) {
             DummyApc7 dummy = (DummyApc7) poIterator.next();
             PlanningObject planning = new PlanningObject();
             planning.setAchievedDate(dummy.getLastUpdate());
             planning.setAircraftType(dummy.getAcType());
             planning.setBaselineDate(dummy.getLastUpdate());
             planning.setDeliverySite(dummy.getDeliverySite());
             planning.setEventId(dummy.getEvtId());
             planning.setEventName(dummy.getEvent());
             planning.setEventStatus(dummy.getEvtStatus());
             planning.setLastUpdate(dummy.getLastUpdate());
             planning.setModel(dummy.getModel());
             planning.setMsn(dummy.getMsn());
             planning.setOperator(dummy.getOperator());
             planning.setOwner(dummy.getOwner());
             planning.setProgram(dummy.getProg());
             planning.setSerial(dummy.getSerial());
             planning.setTargetDate(dummy.getLastUpdate());
             planning.setVersion(dummy.getVersion());
             planning.setVersionRank(dummy.getVersionRank());
             LogCvaultImport.code(800).info("A7|Event name: "+planning.getEventName()+" - MSN: "+planning.getMsn()+" - Delivery site: "+planning.getDeliverySite());
             listPlanningObject.add(planning);        
        }
    } catch (DAOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    LogCvaultImport.code(1000).debug("A7: end retrievePlannings");
}

}

我从数据库中检索一个对象。然后我使用DB数据从PlanningObject类填充List。 我不知道如何实现关于它的jUnit测试用例。 我听说过模拟?

谢谢你们!

1 个答案:

答案 0 :(得分:1)

模拟就像一个假人。模拟数据库意味着要通过某个Java对象来模拟它,而不是访问真正的数据库(从而避免依赖)。在您的情况下,如果DummyApc7DAOFactory 一个接口(请参阅抽象工厂模式),那么您可以实现接口的Junit版本,该版本返回带有值的DummyApc7实例您可以测试(使用JUnit框架的assert方法)。

要实现这一点,您必须相应地重新设计代码(并确保LogCvaultImport不会造成任何麻烦)。应用程序代码中带有静态方法的类总是在单元测试时要避免的另一个依赖源。

在正确的 TDD(测试驱动开发)方法中,您可以设置Apc7Engine一个单元测试友好DummyApc7DAOFactory实例,该实例在retrievePlannings()中进行调用像这样dummyApc7DAOFactory.getDAO().getDummyApc7();(请注意,这不再是抽象方法调用)。附加代码如下所示:

//AbstractDummyApc7DAOFactory.java
public class AbstractDummyApc7DAOFactory {
    /** @param real true, for real DAOFactory, false for Junit testing*/
    public static DummyApc7DAOFactory create(boolean real) {
        if (real) {
            //create and return the real DAOFactory object
        }
        else {
            //return dummy implementation for Junit testing, better define in separate class
            return new DummyApc7DAOFactory() {
                public DummyApc7DAO getDAO() {
                    return new DummyApc7DAO() {
                        public List getDummyApc7() {
                            List dummyList = new ArrayList();
                            testApc7 = new DummyApc7();
                            testApc7.setVersion("1.Unit.Test");
                            //....
                            dummyList.add(testApc7);
                            return dummyList;
                        }
                    };
                }
            };
        }
    }
}

//test code in junit test class
@Test
public void testRetrievePlannings() {
    DummyApc7DAOFactory fac = AbstractDummyApc7DAOFactory.create(false);
    testObj.setDummyApc7DAOFactory(fac);
    testObj.retrievePlannings();
    PlanningObject testPO = test.getListPlanningObject().get(0);
    assertEquals(testApc7.getVersion(), testPO.getVersion()); 
    //...
}

如果无法重新设计代码, Mockito 可能有所帮助。在这里,您不必模拟数据库,而是存根DummyApc7DAOFactory类的方法。但是有一些限制:Mockito不能存在最终或匿名类。如果是这种情况,则必须重新设计代码。如果没有,快速而肮脏的解决方案可能如下所示:

public class  RetrievePlanningsTest {       
        private DummyApc7 testApc7;
        private Apc7Engine testObj = new Apc7Engine();

        @Before
        public void setUp() {
            DummyApc7DAOFactory mockedObj = mock(DummyApc7DAOFactory.class);
            List dummyList = new ArrayList();
            testApc7 = new DummyApc7();
            testApc7.setVersion("1.Unit.Test");
            //....
            dummyList.add(testApc7);
            when(DummyApc7DAOFactory.getDAO().getDummyApc7()).thenReturn(dummyList);
        }

        @Test
        public void testRetrievePlannings() {
            testObj.retrievePlannings();
            PlanningObject testPO = testObj.getListPlanningObject().get(0);
            assertEquals(testApc7.getVersion(), testPO.getVersion()); 
            //...
        }
}