在 JUnit 的 for 循环中模拟 if 条件

Mocking an if condition within a for loop in JUnit

我正在尝试使用 Mockito 和 JUnit 模拟一个方法。出于某种原因,尽管测试满足 if 语句,但它一直说永远不会调用嵌入式方法。

这是我正在测试的方法:

    public List<LifeProduct> prune(List<LifeProduct> products) {
        for (LifeProduct product : products) {
            int id = product.getProductAnalyticsIdentifier();
            boolean deleteAnnuity = id > 10014;
            boolean deleteLifeInsurance = product.getLifeInsurance()
                .getHighLevelLifeInsuranceGroupName()
                .equals("string");
            
            if (deleteAnnuity) {
                annuityService.deleteAnnuityById(id);
            }
            if (deleteLifeInsurance) {
                lifeInsuranceService.deleteLifeInsuranceById(id);
            }
        }
        
        return products;
    }

这是我对迭代器设置的测试:

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
  
        when(mockList.iterator()).thenReturn(mockIterator);
        when(mockIterator.hasNext()).thenReturn(true, false);
        when(mockIterator.next()).thenReturn(mockProduct);
    }

    @Test
    public final void testPrune() throws Exception {
        for (LifeProduct mockProduct : mockList) {
            mockProduct.setProductAnalyticsIdentifier(99999999);
            doNothing().when(annuityService).deleteAnnuityById(anyInt());
            List<LifeProduct> response = lifeProductDelegate.prune(mockList);
            assertNotNull(response);
            verify(annuityService).deleteAnnuityById(anyInt());
        }
    }

您的测试有两个问题:

您正在使用 mockList,因此使用 mockIterator.hasNext()

的两个值之一

你说调用mockIterator.hasNext()时应该先returntruefalse。这里的问题是您的测试方法遍历 mockList,因此需要调用 mockIterator.hasNext(),然后使用第一个 true 值。被测试的方法 #prune() 然后也尝试迭代列表,但只会得到第二个,即 false 值,从而跳过循环。您的测试方法中不需要循环,因此您可以而且应该将其删除。

您设置错误mockProduct

第二期mockProduct.setProductAnalyticsIdentifier(99999999)mockProduct 是一个模拟,因此当未通过 when(mockProduct...)... 配置时,这些方法不会执行任何操作。所以值 99999999 没有存储在任何地方并且 #getProductAnalyticsIdentifier() 在测试中 returns 0,默认值。你真正想要做的是配置 getter 方法,例如:

when(mockProduct.getProductAnalyticsIdentifier()).thenReturn(999999);

现在 mockProduct 将 return 当 #prune() 请求 id 并稍后将其与 10014 进行比较时的值。