Mockito不断返回空列表

时间:2018-09-25 12:00:26

标签: java spring unit-testing mockito

我正在对Mockito中的方法进行单元测试,即使我已经初始化了要返回的列表,mockito仍会发送一个空的零大小列表。

这是要测试的代码。请注意,nonCashIncludedPaymentPlanActive始终为true(模拟)。

    List<DebtAccountTransaction> debtAccountTransactionList = null;

    boolean nonCashIncludedPaymentPlanActive = balancingPlanService.checkNonCashIncludedPaymentPlanParameter(debtAccountId);


    if (nonCashIncludedPaymentPlanActive) {
        debtAccountTransactionList = debtAccountTransactionDao
                .getDebtAccountTransactionListByDebtAccountIdListWithCN(baseDebtIdAccountList, null);
    } 
    if (debtAccountTransactionList.isEmpty()) {
        throw new SfcException("DISPLAY.PAYMENT_PLAN_WITH_NO_BALANCE_SERVICE_FILE_CLOSED");
    }

这条语句一直返回我在模仿程序中嘲笑的列表,并向其中添加了一个项目,在这里它返回一个空列表。

debtAccountTransactionList = debtAccountTransactionDao
                .getDebtAccountTransactionListByDebtAccountIdListWithCN(baseDebtIdAccountList, null);

那当然会被这条线抓住

if (debtAccountTransactionList.isEmpty()) {
        throw new SfcException("DISPLAY.PAYMENT_PLAN_WITH_NO_BALANCE_SERVICE_FILE_CLOSED");
    }

为了避免这种执行路径,我在Mockito中做了以下操作:

when(debtAccountTransactionDao.getDebtAccountTransactionListByDebtAccountIdListWithCN(baseDebtIdAccountList, null)).thenReturn(
            debtAccountTransactionList);

,并且btcAccountTransactionList的声明为:

DebtAccountTransaction debtAccountTransaction = spy(DebtAccountTransaction.class);
    debtAccountTransaction.setId(2L);


    List<DebtAccountTransaction> debtAccountTransactionList = new ArrayList<DebtAccountTransaction>();
    debtAccountTransactionList.add(debtAccountTransaction);

我尝试模拟列表,尝试使用不同的参数捕获器,但似乎没有任何效果。当我对其进行调试时,Mockito确实会填充 debtAccountTransactionList ,但列表为空,因此会失败。

有关如何确保Mockito发送非空非零列表的任何帮助,以便它可以绕过 isEmpty()检查。

3 个答案:

答案 0 :(得分:2)

编写测试的一个很好的经验法则,尤其是使用Mockito之类的模拟库时:不要将存根与验证混为一谈。存根(when是要使您的被测系统(SUT)进入所需状态,而不是关于断言有关SUT行为的任何内容。

在Mockito中,对SUT的行为进行断言的方法是在之后使用verify调用运行SUT。如果您没有任何verify调用,那么您实际上并没有断言任何内容,并且SUT可能会在测试未捕获的情况下发生异常,这显然是一件坏事。

因此,通常最好使用于存根(when)的匹配器尽可能广泛,因为存根的目的只是确保您进入正确的测试用例。例如,您可以并且经常应该在any()调用中使用when()之类的匹配器。如果这样做了,您就可以避开这里遇到的问题。

如果要对SUT实际用作参数的值进行断言,请使用verify进行操作,或者可以通过捕获该值并直接对其进行附加断言来进行。

答案 1 :(得分:0)

您是否将代码放在任何地方,如:

debtAccountTransactionDao = Mockito.mock(NameOfTheClassOfThisDebtAccountObject.class);

您应在调用方法getDebtAccountTransactionListByDebtAccountIdListWithCN之前放入类似的内容,以使其知道应该使用模拟行为,而不是方法的正常行为(可能会返回一个空列表)。

答案 2 :(得分:0)

  

问题是模拟创建/行为注册。这与您在方法中输入的内容不匹配,因此返回默认的返回空列表的行为。

M. Deinum

指出

因此,Mockito接受参数存在问题,它将忽略我的存根,然后默认情况下返回一个空列表。

我通过确保将 baseDebtIdAccountList 对象传递给函数来解决此问题,当(debtAccountTransactionDao.getDebtAccountTransactionListByDebtAccountIdListWithCN(baseDebtIdAccountList,null))。thenReturn(             该代码的其余部分完全相同(btcAccountTransactionList)。因此,参数不匹配,Mockito使用默认的方式使用空列表。