代码之家  ›  专栏  ›  技术社区  ›  Andulos

如何模拟调用没有返回值的其他方法的方法

  •  0
  • Andulos  · 技术社区  · 6 年前

    public boolean validatePersonForBenefitsProcessing(PersonDTO person) {
            boolean continueProcessing = false;
            if (person.isPersonOnLeave()) {
                if (person.isBenefitsCoverage()) {
                    if (person.isPersonDriver()) {
                        continueProcessing = true;
                    } else {
                        if(person.isPersonOnSTD()) {
                            continueProcessing = false;
                        } else {
                            continueProcessing = true;
                            person.setSendPersonToInternal(true);
                        }
                    }
                }
            }
            return continueProcessing;
        }
    
    0 回复  |  直到 6 年前
        1
  •  3
  •   second    6 年前

    如果要测试此方法(例如:提高覆盖率), PersonDTO 并通过声明方法调用的结果来定义它应该显示的行为。

    一个例子如下所示:

    public void test() {
        PersonDTO personMock = mock(PersonDTO.class);
    
        when(personMock.isPersonOnLeave()).thenReturn(true);
        when(personMock.isBenefitsCoverage()).thenReturn(true);
        when(personMock.isPersonOnSTD()).thenReturn(false);
    
        Assert.assertTrue(validatePersonForBenefitsProcessing(personMock));
    
        ArgumentCaptor<Boolean> captor = ArgumentCaptor.forClass(Boolean.class);
        verify(personMock).setSendPersonToInternal(captor.capture());
    
        Assert.assertTrue(captor.getValue());
    }
    

    但是,如果您可以轻松创建 潘森托 它建议这样做。模拟通常应用于不能自己创建的“复杂”对象。


    如果你的目的是模仿方法本身, SomeClass 它可能是这样的:

    SomeClass mock = mock(SomeClass.class);
    when(mock.validatePersonForBenefitsProcessing(any(PersonDTO.class))).thenReturn(true);
    

    但是,由于类同时修改传入值和返回值,这是不合适的,因为传入对象的修改不会发生。

    您将被迫执行以下操作:

    SomeClass mock = mock(SomeClass.class);
    when(mock.validatePersonForBenefitsProcessing(any(PersonDTO.class))).thenAnswer(new Answer<Boolean>() {
    
        @Override
        public Boolean answer(InvocationOnMock invocation) throws Throwable {
    
            PersonDTO dto = (PersonDTO) invocation.getArgument(0);
            dto.setSendPersonToInternal(true);
    
            return true;
        }
    });
    

    作为 @chrylis 如前所述,此类行为可能会让其他开发人员感到惊讶,因此应尽可能避免。而且它使测试更容易;)

    他说,这个方法中没有任何东西真正需要您进行这种模拟,因为您可以通过操纵输入参数来自由控制代码所采用的路径。