0

我想测试私有方法的行为。“moveDataToArchive”方法执行 4 个步骤。

它是 4 倍:计算日期 + 调用子方法。

这是我的测试:

@Test
    public void testMoveData2Archive() throws Exception{

    final long now = 123456789000L;

    //Necessary to make the archivingBean runable.
    Vector<LogEntry> logCollector = new Vector<LogEntry>();
    Deencapsulation.setField(archivingBean, "logCollector", logCollector);

    new NonStrictExpectations(archivingBean) {
        {       //Lets fake the DB stuff.
            invoke(archivingBean, "getConnection");result = connection;
            connection.prepareStatement(anyString); result = prepStatement;
            prepStatement.executeUpdate(); returns(Integer.valueOf(3), Integer.valueOf(0), Integer.valueOf(3));
        }
    };

    new NonStrictExpectations(props) {
        {    //This is important. The numbers will be used for one of each 4 submethods
            props.getProperty(ArchivingHandlerBean.ARCHIVING_CREDMATURITY_OVER_IN_DAYS); result = "160";
            props.getProperty(ArchivingHandlerBean.ARCHIVING_CREDHIST_AGE_IN_DAYS); result = "150";
            props.getProperty(ArchivingHandlerBean.ARCHIVING_DEBTHIST_AGE_IN_DAYS); result = "140";
            props.getProperty(ArchivingHandlerBean.ARCHIVING_LOG_AGE_IN_DAYS); result = "130";
        }
    };

    new Expectations() {
        {
            Date expected = new Date(now - (160 * 24 * 60 * 60 * 1000));
            invoke(archivingBean, "moveCreditBasic2Archive", expected);

            expected = new Date(now - (150 * 24 * 60 * 60 * 1000));
            invoke(archivingBean, "moveCreditHistory2Archive", expected);

            expected = new Date(now - (999 * 24 * 60 * 60 * 1000));
            invoke(archivingBean, "moveDebtorHistory2Archive", expected);

            expected = new Date(now - (130 * 24 * 60 * 60 * 1000));
            invoke(archivingBean, "moveLog2Archive", expected);

        }
    };

    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(now);
    Deencapsulation.invoke(archivingBean,"moveDataToArchive",cal, props);
}

有什么问题?请参阅第三个预期日期。这是错误的!(999 而不是 140)。我还改变了通话的顺序。我什至将这些私有方法公开并尝试了它。所有这些变化都没有改变结果:测试是绿色的。

这里有什么问题?为什么测试是绿色的?

4

2 回答 2

0

archivingBean该测试通过混合对同一个模拟 ( )的严格和非严格期望来滥用模拟 API 。在这个 mock 上记录的第一个期望是非严格的,因此 JMockit 将其视为整个测试的非严格 mock。

编写测试的正确方法是在测试结束时将严格期望块(具有 4 次“子方法”调用的块)转换为验证块。

(顺便说一句,整个测试有几个问题。1)一般来说,私有方法应该通过一些公共方法间接测试。2)此外,不应模拟私有方法,除非有充分的理由否则 - 在这种情况下,我可能会编写一个测试来验证输出文件的实际内容。3)不要不必要地嘲笑事物,例如props-props.setProperty可以用来代替,我想。4)使用自动装箱Integer.valueOf(3)--> 3)。

于 2013-06-25T12:35:12.040 回答
0

@Rogério:您的假设并不完全有效。即我没有setProperty()。我尝试的是使用验证块。

可悲的是,我不了解 JMockit 足以让它运行......

我做了两件事。首先,我尝试模拟 4 个私有方法。我只想看看他们是否被调用。但我不希望有逻辑运行。我通过像这样扩展第一个 NonStrictExpectations-Block 来尝试它:

 new NonStrictExpectations(archivingBean) {
        {
            invoke(archivingBean, "getConnection");result = connection;
            connection.prepareStatement(anyString); result = prepStatement;
            prepStatement.executeUpdate(); returns(Integer.valueOf(3), Integer.valueOf(0), Integer.valueOf(3));
            //New part
            invoke(archivingBean, "moveCreditBasic2Archive", withAny(new Date()));
            invoke(archivingBean, "moveCreditHistory2Archive", withAny(new Date()));
            invoke(archivingBean, "moveDebtorHistory2Archive", withAny(new Date()));
            invoke(archivingBean, "moveLog2Archive", withAny(new Date()));
        }
    };

另一方面,我将期望块向下移动并使其成为验证块。现在 JUnit 失败了

mockit.internal.MissingInvocation: Missing invocation of:
de.lpm.ejb.archiving.ArchivingHandlerBean#moveCreditBasic2Archive(java.util.Date pOlderThan)
with arguments: Tue Feb 03 03:39:51 CET 2009
on mock instance: de.lpm.ejb.archiving.ArchivingHandlerBean@1601bde
at de.lpm.ejb.archiving.ArchivingHandlerBean.moveCreditBasic2Archive(ArchivingHandlerBean.java:175)
[...]
Caused by: Missing invocation

这是 ArchivingHandlerBean.java 中的第 170-175 行:

170: Connection connection = getConnection();
171: SQLService service = new SQLService(connection);
172:            
173: PreparedStatement prepStmtMove = null;
174:            
175: Vector<HashMap<String, String>> where_clauses = new Vector<HashMap<String,String>>();

我只想验证 4 个私有方法是否在正确的日期执行。

于 2013-06-25T14:39:35.407 回答