【问题标题】:How to mock this inside object如何模拟这个内部对象
【发布时间】:2018-11-28 06:15:40
【问题描述】:

我有这样的代码

String str = message.getMBC()
            .values()
            .stream()
            .findFirst()
            .get()
            .getId();

其中 getMBC() 返回一个 LinkedHashMap,键为 String,值为某个 ObjectA。

我正在编写一个测试用例,其中 str 用于某些逻辑。我只是想模拟这条消息以返回一个字符串值,而无需处理linkedhashmap 等的所有内部复杂性。

我在我的测试用例中尝试过这个,其中消息是一个模拟对象。

when (message.getMBC()).get(anyObject()).getId()).thenReturn("STRING");

我知道我做的不对,因为 getMBC() 也应该是模拟的。

模拟这个对象的最简单方法是什么?

【问题讨论】:

    标签: java mocking mockito powermock


    【解决方案1】:

    像下面的代码一样,您可以逐步模拟内部对象。

    Message mockMessage = mock(Messsage.class);
    when(mockMessage.getMBC()).thenReturn("AnyObject");
    AnyObject mockAnyObject = mock(AnyObject.class);
    when(mockAnyObject.getId()).thenReturn("STRING");
    

    尝试用上述方式模拟所有对象

    【讨论】:

      【解决方案2】:

      错误的方法。你不模拟地图。故事结束。

      含义:任何类型的集合都只是:对象的集合。每当您考虑模拟 容器 时,您很可能做错了什么。

      你看,模拟是一个强大的工具,理想情况下你永远不会使用它。你真的只有在没有更好的方法来测试你的东西时才使用它。

      除此之外:您应该真正了解您的测试在做什么。因此,与其去when(x.get(any())).thenReturn(y),您应该更喜欢简单地拥有一个包含恰好测试所需的值的独特地图。 any() 说:“我不知道将使用什么参数”。但你可能应该知道这一点。

      所以,长话短说:(如果有的话),您应该只模拟message 对象以在调用getMBC() 时返回一个自定义 地图实例。您的方法为您的测试增加了“模拟复杂性”。这导致您的测试与实现细节紧密耦合。没有好的理由。

      【讨论】:

        猜你喜欢
        • 2023-03-12
        • 1970-01-01
        • 2018-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-06
        相关资源
        最近更新 更多