有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Mockito的inoder()和集合/映射

我有以下情况:我的类保留两个对象的标识集

这些集合逐渐被一些实例填充,在测试用例中,它们被模拟填充

然后我的类有一个调用,该调用对一个集合的内容进行处理,然后对另一个集合的内容进行处理。这就是我正在测试的呼叫

处理集合的顺序很重要。在集合中处理单个对象的顺序并不重要,事实上,它取决于如何将标识散列分配给集合中的模拟

所以在我的情况下,我有一个偏序:所有这些对象都必须在任何这些对象之前被处理

问题是,我如何用Mockito来表达它?inOrder()崩溃是因为我必须指定对象的确切顺序,而这不是常量


共 (1) 个答案

  1. # 1 楼答案

    讨论使用Mockito时如何处理集合和地图。因此,我们必须根据具体情况区分4种情况

    • 集合或映射是输入的还是在方法内部创建的(输入意味着通过方法参数、类变量或可存根的方法调用返回它)
    • 集合或映射是否在方法内部被访问或迭代(或来自同一类或被调用的超类的另一个方法,因此无法存根)

    这将导致4种组合或4种可能的情况

    1. 集合或映射是被测试方法的输入参数,该方法将其传递给另一个方法或返回它,但不接触它。 在这种情况下,只需模拟集合或地图。没问题

    2. 集合或映射是被测试方法的输入参数,该方法访问(或迭代)它。 在这种情况下,将创建包含一个或多个模拟的集合或集合。在这种情况下,永远不要模拟集合或映射本身,因为在使用for循环或流进行迭代时,您不知道调用了哪些方法,也不知道需要存根哪些方法(这取决于JRE的实现!)。 因为您必须在调用方法之前自己创建它,所以您可以决定将使用什么实现。如果它包含2个或更多模拟对象,或者正在测试的方法向其中添加对象,则创建一个有序的集合或映射。 如果方法不应该修改它,而只应该读取它,那么创建一个不可修改的集合或映射。我喜欢使用收藏。单身,收藏。单音表和数组。在测试中列出

    3. 被测试的方法创建并填充集合,但不访问或迭代它。 如果该方法将对象添加到集合或映射(作为参数传入),然后将集合或映射传递到另一个映射或返回它,则没有问题。 在这种情况下,不存在依赖于迭代顺序的验证调用。您只需要在之后断言它的内容(当返回时,或者如果没有返回而是传递给另一个方法,则使用captor)

    4. 被测试的方法创建并填充集合,并访问或迭代它。 当该方法创建集合或映射并向其中添加mock,然后对其进行迭代并对这些mock执行操作时,如果您使用的是inoder,并且集合或映射没有排序,那么确实存在问题。 在这种情况下,您应该尝试将该方法拆分为两个方法:一个方法创建并填充集合或映射(在情况3中结束,它可以是工厂类中的工厂方法),另一个方法访问或迭代它(在情况2中结束)。仅仅创建一个工厂方法并从已经存在的方法调用它就足以解决这个问题

    当包含被测试方法的类有一个集合或映射作为类变量时,如果该方法访问或修改该方法,则可以将其视为该方法的输入,如果该方法设置该方法,则将其作为输出。 但是,如果它是一个没有setter或getter的私有或受保护类变量,那么在调用方法之前,您可能需要使用反射来使用mock或包含一个或多个mock的set或map来设置它,或者在调用方法之后获取并验证它