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

时间:2019-07-28 06:09:46

标签: java unit-testing junit mockito

我对Mockito非常陌生。我想为下面的方法编写一个模拟。我怎么写呢?我的模拟方法是什么样的?

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;
    }

2 个答案:

答案 0 :(得分:1)

问题是您这样做的目的是什么?

如果您想测试此方法(例如:提高覆盖率), 您可以创建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());
}

但是,如果您可以轻松地自己创建PersonDTO对象并提供必要的值, 建议这样做。通常应将模拟用于不能简单地创建自己的“复杂”对象。


如果您的目的是模拟方法本身, 然后假设您的班级为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所言,这样的行为可能会使其他开发人员吃惊,因此应尽可能避免。它还使测试容易得多;)

正如@chrylis所说的那样,此方法中没有任何内容真正需要您进行这种模拟,因为您可以通过操纵输入参数自由地控制代码所采用的路径。

答案 1 :(得分:-1)

对于这种方法,您可以使用

  

when(mockObject.validatePersonForBenefitsProcessing(personClassObject))。thenReturn(anyBoolean()/(true / false));

如果您使用void方法(如提及的那样)没有返回值,则可以使用

  

doNothing()。when(mock_object_of_class).any_void_method(必填参数);