使用Mockito调用真实方法

时间:2020-07-10 01:44:54

标签: java spring spring-boot mockito

我正在使用JDK 11和spring boot。 我正在实现rest API,共有3层:

  • 控制器
  • 服务层
  • 数据访问层

我在数据访问层有针对接口的类,而在服务层没有任何接口。

我使用MockMvc,Mockito等编写了集成测试,以测试控制器公开的每个点的整个路径。在我尝试在服务层引入接口之前,这不是问题。

最初,我只嘲笑存储库/ Daos。这样的类结构如下:

    public interface ClientRepo{
    ......
    }

    public class ClientRepoImpl implements ClientRepo{
    ......
    }

将返回的数据模拟为:

    @MockBean 
    private ClientRepo client;

    ....
    Mockito.when(client.isExistFkUnitId(Mockito.any(UUID.class))).thenReturn(false); 

到目前为止一切都很好。

现在,我在服务层引入接口为:

    public interface ClientService{
    ......
    }

    public class ClientServiceImpl implements ClientService{
    ......
    }

并尝试了(尝试调用实际的服务方法)

    @MockBean 
    private ClientService clientService;

    ....
    Mockito.when(clientService.isExistFkUnitId(Mockito.any())).thenCallRealMethod();

但是总是空着什么也没得到

有没有办法使真正的方法调用保持接口?

2 个答案:

答案 0 :(得分:0)

嗯,没有可调用的“真实”方法。 (忽略如今接口中的默认方法已成为事实)

通常,应该以隔离的方式为目标类编写单元测试。像这样,您也总是在“测试”“ isExistFkUnitId”方法。 您可以将模拟设置为特定值:

Mockito.when(clientService.isExistFkUnitId("valueA").thenReturn("answerA");
Mockito.when(clientService.isExistFkUnitId("valueB").thenReturn("answerB");

无论如何...回答您的实际问题:

如果可能的话,可以以所需方法起作用的方式实例化实现,并通过模拟调用它:

ClientServiceImpl clientServiceImpl = new ClientServiceImpl(...);
// spaghetti code only for demonstration purposes ;)
Mockito.when(clientService.isExistFkUnitId(Mockito.any())).then(i -> clientServiceImpl.isExistFkUnitId((String) i.getArguments()[0]));

POC测试:

@Test
public void testit() {
    Myclass myclass = new Myclass();
    Myinterface mock = Mockito.mock(Myinterface.class);
    Mockito.when(mock.myMethod(Mockito.any())).then(i -> myclass.myMethod((String) i.getArguments()[0]));

    assertThat(mock.myMethod(" works")).isEqualTo("yeehaa works");
}

public interface Myinterface {
    String myMethod(String params);
}

public static class Myclass implements Myinterface {
    @Override
    public String myMethod(String params) {
        return "yeehaa" + params;
    }
}

并非完美的解决方案,但如果无法解决,它应该可以工作。

答案 1 :(得分:0)

我认为您想在要调用real方法的字段上使用@Spy注释,而不是@Mock注释。我没有碰巧有一个例子来验证这一点。 https://javadoc.io/doc/org.mockito/mockito-core/2.21.0/org/mockito/Spy.html

然后您可以执行doCallRealMethod().when(clientService.isExistFkUnitId(Mockito.any()))。 因为使用间谍对象,所以您调用doReturn/when而不是when/doReturnhttps://javadoc.io/doc/org.mockito/mockito-core/2.21.0/org/mockito/Mockito.html#do_family_methods_stubs

相关问题