Mockito:使用intThat匹配集合中包含的原始类型参数

Mockito:使用intThat匹配集合中包含的原始类型参数

本文探讨了在mockito中,当需要对方法参数进行模拟,使其匹配一个特定集合中包含的原始类型值时,如何克服`in()`方法缺失的挑战。通过利用`argumentmatchers.intthat()`结合lambda表达式,或进一步封装成辅助方法,可以优雅地实现这一需求,提升测试代码的灵活性和可读性。

Mockito中参数匹配的挑战与intThat的应用

在编写单元测试时,我们经常需要使用Mockito框架来模拟对象的行为。有时,我们希望一个被模拟的方法仅在其某个参数的值包含在一个特定集合中时才执行预设的动作。例如,对于一个方法List getValuesFor(int arg),我们可能希望当arg的值是1、2或3中的任意一个时,该方法返回特定的结果。

然而,Mockito的ArgumentMatchers和AdditionalMatchers中并没有直接提供一个类似in(1, 2, 3)的方法来匹配原始类型(如int)是否包含在一个给定的集合中。这使得直接表达此类匹配逻辑变得不直观。

利用intThat实现集合包含匹配

为了解决这个问题,我们可以利用Mockito提供的ArgumentMatchers.intThat()方法。intThat()接受一个org.mockito.ArgumentMatcher接口的实例,或者更简洁地,一个返回布尔值的java.util.function.Predicate函数式接口的Lambda表达式。

以下是实现上述需求的具体步骤和示例:

立即进入“豆包AI人工智官网入口”;

立即学习“豆包AI人工智能在线问答入口”;

1. 定义被模拟的方法

首先,假设我们有一个服务接口或类,其中包含以下方法:

public interface MyService {    List getValuesFor(int arg);}

我们希望模拟MyService的一个实例,使其在getValuesFor方法接收的arg值为1、2或3时,返回特定的列表。

2. 使用intThat结合Lambda表达式

最直接的方法是使用intThat并传入一个Lambda表达式,该表达式检查传入的int参数是否包含在一个预定义的集合中。

import org.junit.jupiter.api.Test;import org.mockito.Mockito;import java.util.List;import java.util.Set;import static org.mockito.Mockito.*;import static org.mockito.ArgumentMatchers.intThat; // 确保导入 intThatpublic class MockitoCollectionMatcherExample {    @Test    void testGetValuesForWithCollectionMatch() {        MyService mockObject = mock(MyService.class);        // 定义期望匹配的集合        Set allowedArgs = Set.of(1, 2, 3);        // 使用 intThat 结合 Lambda 表达式来匹配参数        when(mockObject.getValuesFor(intThat(x -> allowedArgs.contains(x))))                .thenReturn(List.of(30, 40, 50));        // 测试匹配的参数        List result1 = mockObject.getValuesFor(1);        System.out.println("Result for arg 1: " + result1); // 输出: [30, 40, 50]        assert(result1.equals(List.of(30, 40, 50)));        List result2 = mockObject.getValuesFor(2);        System.out.println("Result for arg 2: " + result2); // 输出: [30, 40, 50]        assert(result2.equals(List.of(30, 40, 50)));        List result3 = mockObject.getValuesFor(3);        System.out.println("Result for arg 3: " + result3); // 输出: [30, 40, 50]        assert(result3.equals(List.of(30, 40, 50)));        // 测试不匹配的参数,此时会调用实际方法(如果不是mock),或者返回null(如果是mock且未stub)        List result4 = mockObject.getValuesFor(4);        System.out.println("Result for arg 4: " + result4); // 输出: null        assert(result4 == null);        // 验证方法调用        verify(mockObject, times(1)).getValuesFor(1);        verify(mockObject, times(1)).getValuesFor(2);        verify(mockObject, times(1)).getValuesFor(3);        verify(mockObject, times(1)).getValuesFor(4); // 即使没有stub,调用也会被记录    }}

在这个例子中,intThat(x -> allowedArgs.contains(x))创建了一个自定义的参数匹配器。当getValuesFor方法被调用时,Mockito会检查传入的int参数x是否在allowedArgs集合中。如果contains(x)返回true,则匹配成功,并返回List.of(30, 40, 50)。

3. 封装为辅助方法提高可读性和复用性

如果需要在多个测试或不同的模拟场景中重复使用相同的匹配逻辑,将Lambda表达式封装成一个独立的辅助方法可以大大提高代码的可读性和复用性。

import org.junit.jupiter.api.Test;import org.mockito.Mockito;import java.util.List;import java.util.Set;import java.util.function.Predicate;import static org.mockito.Mockito.*;import static org.mockito.ArgumentMatchers.intThat;public class MockitoCollectionMatcherHelperExample {    // 辅助方法:判断一个int值是否包含在给定的集合中    private static Predicate isOneOf(Integer... values) {        Set allowedValues = Set.of(values);        return x -> allowedValues.contains(x);    }    @Test    void testGetValuesForWithHelperMethod() {        MyService mockObject = mock(MyService.class);        // 使用封装后的辅助方法        when(mockObject.getValuesFor(intThat(isOneOf(1, 2, 3))))                .thenReturn(List.of(300, 400, 500));        // 测试匹配的参数        List result1 = mockObject.getValuesFor(1);        System.out.println("Result for arg 1 (helper): " + result1);        assert(result1.equals(List.of(300, 400, 500)));        List result4 = mockObject.getValuesFor(4);        System.out.println("Result for arg 4 (helper): " + result4);        assert(result4 == null);        verify(mockObject, times(1)).getValuesFor(1);        verify(mockObject, times(1)).getValuesFor(4);    }}

通过isOneOf(1, 2, 3)这样的辅助方法,测试代码变得更加简洁和富有表达力,就像Mockito内置的匹配器一样。

注意事项与总结

类型匹配器: intThat()是专门为int类型设计的。Mockito还提供了其他类似的类型匹配器,如longThat()、byteThat()、shortThat()、charThat()、floatThat()、doubleThat()和通用的argThat()(用于对象类型),它们都接受相应的Predicate或ArgumentMatcher。灵活性: 这种*That()系列的匹配器极大地增强了Mockito的灵活性,允许开发者定义任何复杂的自定义匹配逻辑,而不仅仅局限于内置的简单匹配规则。可读性: 尽管Lambda表达式很强大,但对于复杂的匹配逻辑,封装成命名清晰的辅助方法或自定义ArgumentMatcher类,能够显著提升测试代码的可读性和可维护性。性能: 在Lambda表达式或自定义匹配器中执行的逻辑应尽量高效,避免在每次参数匹配时进行昂贵的操作。

通过上述方法,即使Mockito没有直接提供in()这样的集合包含匹配器,我们也能通过intThat()(或其他*That()匹配器)结合Lambda表达式或辅助方法,优雅且高效地实现对原始类型参数的集合包含匹配。这使得Mockito在处理复杂参数匹配场景时依然保持了强大的能力和灵活性。

以上就是Mockito:使用intThat匹配集合中包含的原始类型参数的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/201647.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月1日 21:30:55
下一篇 2025年11月1日 21:33:36

相关推荐

  • 使用 html css 和 javascript 制作太阳和月亮动画

    Day-Night Toggle body, html { margin: 0; padding: 0; height: 100vh; display: flex; justify-content: center; align-items: center; font-family: Arial, s…

    2025年12月19日 好文分享
    000
  • 如何实现豆瓣电影搜索影院悬浮框自动隐藏?

    豆瓣电影搜索影院悬浮框的实现 在浏览豆瓣电影网站时,右上角搜索影院功能呈现了 intéressante 的交互效果。点击“广州”后出现的悬浮框,在点击悬浮框以外的区域时会自动隐藏。 解决此问题的方法是为 body 元素绑定一个点击事件监听器。该事件处理程序将检查点击目标是否包含在悬浮框内。如果不是,…

    2025年12月19日
    000
  • 豆瓣电影网页影院搜索框是如何实现自动隐藏效果的?

    豆瓣电影网页影院搜索框自动隐藏效果 在豆瓣电影网页上,当用户点击“广州”显示影院列表后,点击列表之外任意区域,列表即可自动隐藏。实现这一效果的方法如下: 对于此问题,一般做法是使用 javascript 或 jquery 等框架在 body 元素上绑定一个 click 事件监听器。当点击事件触发时,…

    2025年12月19日
    000
  • JavaScript 中的生成式人工智能? Microsoft 的 GenAIScript、Svelte Nextjs 等

    欢迎来到新版“本周 JavaScript ”! 今天,我们从 Microsoft 获得了一些改变游戏规则的更新,即期待已久的 Svelte 5 版本和新的 Next.js 15 版本 – 还有更多!  微软GenAIScript 2024 年都是关于人工智能的,而 Microsoft 正…

    2025年12月19日
    000
  • 如何解决构建搜索框历史记录时遇到的失焦问题?

    做搜索框的历史记录时遇到的问题 在构建搜索框的历史记录时,您可能遇到了以下问题: 问题一: 点击历史记录项会触发输入框失焦,导致历史记录无法正常显示。问题二: 清除输入框时也会触发失焦,从而导致搜索框不符合设计要求。 解决方案: 问题一: 使用一个容器元素将输入框和历史记录列表包裹起来。添加一个“点…

    2025年12月19日
    000
  • 提高开发效率的 JavaScript 技巧

    javascript 是前端开发的重要语言,但许多开发人员可能不熟悉它的一些强大功能。这里有 10 种有价值的 javascript 技术,可以提高编码效率。 1. 使用 flatmap 进行数组操作 flatmap() 是一种多功能方法,它结合了 map() 和 flat() 的功能,将数组扁平化…

    2025年12月19日
    000
  • 如何实现 El-Table 数据合并,且满足特定条件下的合并规则?

    el-table 数据合并优化 问题描述 需要实现 el-table 数据合并,但遇到问题:只要有相同值就可以合并,但实际要求为: 其他列有相同值正常合并诉求类型中相同值合并时,诉求利用率也需合并以上规则在细分类型和细分利用率中也适用 优化方案 数据清洗: 标记第一次出现的值 ismerge = f…

    好文分享 2025年12月19日
    000
  • 小程序如何自动切换语言,才能兼顾精准性和适用性?

    根据小程序实现自动切换语言 对于多语言环境的小程序,如何自动切换语言是一个常见问题。 方法一:根据用户定位 这种方法基于用户定位来获取所在国家,并根据国家对应语言设置。然而,这种方法存在一定的局限性,如用户可能不会允许位置共享。 方法二:通过 wx.getsysteminfo 这是微信官方提供的 a…

    2025年12月19日
    000
  • 多语言小程序如何实现语言自动切换?

    多语言小程序切换语言方案 对于多语言小程序的语言自动切换,业界提供了两种主流方案: 一、基于用户定位获取用户所在国家 调用 wx.getsysteminfo 获取用户语言。根据用户定位获取用户所在国家。然后切换到与该国家匹配的语言环境。 二、直接通过微信自带的 wx.getsysteminfo 获取…

    2025年12月19日
    000
  • 小程序多语言环境如何自动切换?

    如何实现小程序多语言环境的自动切换 为了实现小程序的多语言环境自动切换,有两种常见的方法: 一、根据用户定位获取语言 获取用户地理位置,确定其所在国家/地区。根据国家/地区加载对应的语言环境。 二、通过微信提供的接口获取语言 调用 wx.getsysteminfo 获取用户设备语言。根据设备语言加载…

    2025年12月19日
    000
  • 如何使用 El-table 合并数据,满足诉求类型和利用率的特殊合并要求?

    el-table数据合并问题 此问题旨在解决el-table合并数据时的特殊需求。 需求说明: 当诉求类型相同且诉求利用率也相同,才能合并诉求利用率。如果诉求利用率存在相同值,但诉求类型不同,则不合并。细分类型和细分利用率的合并规则与此类似。 解决方法: 要在组件中实现此需求,需要对数据进行预处理,…

    2025年12月19日
    000
  • 如何按相邻数据对后台异步返回数据进行排序?

    如何按相邻数据对后台异步返回数据进行处理? 后端返回的数据按 staff 字段默认排序,前端希望根据 appeal_type 和 detail_appeal_type 字段对数据进行排序,以便相邻记录具有相同的字段值。 解决方法: 首先,按照 appeal_type 字段排序: list.tosor…

    2025年12月19日
    000
  • 小程序多语言环境自动切换:如何实现用户语言的精准获取和应用?

    小程序多语言环境自动切换 在开发小程序时,需要针对不同语言的用户提供不同的语言环境,以便他们更好地理解和使用小程序。那么,如何实现小程序的语言自动切换呢? 解决方案 小程序获取用户语言主要有两种方式: 根据用户定位获取用户所在国家,然后切换语言。直接通过微信提供的 wx.getsysteminfo …

    2025年12月19日
    000
  • 如何对异步获取的数据进行多字段排序?

    如何对异步获取数据进行排序处理 后端返回的数据通常按特定字段排序,但前端可能会需要根据其他字段进行重新排序,例如根据多种字段相邻排序。本问题中,需要对后端返回的员工工作数据按 appeal_type 和 detail_appeal_type 字段相邻排序。 解决方案: 首先按 appeal_type…

    2025年12月19日
    000
  • 多语言小程序中,如何实现自动语言切换?

    多语言小程序的语言切换方案 在小程序中实现多语言环境时,如何自动切换语言是一个常见问题,通常有两种常见的解决方案: 1. 根据用户定位获取用户所在国家,然后切换语言 这种方法需要通过微信提供的 api wx.getlocation 来获取用户的位置信息,然后根据位置信息确定用户的所在国家,再根据国家…

    2025年12月19日
    000
  • 使用 TypeScript 和 ioredis 在 Nodejs 中构建高性能缓存管理器

    使用基于 ioredis 构建的多功能、易于使用的缓存管理器来提升 node.js 应用程序的性能。简化缓存、优化效率并简化操作。 我根据自己的需求开发了一个基于 ioredis 的类,重点关注易用性和性能。它包括 typescript 支持,旨在实现简单使用和高效操作。它仍然可以进一步改进和优化,…

    2025年12月19日
    000
  • 如何对异步返回的数据进行多级排序?

    对异步返回的数据进行排序和处理,将相邻数据展示出来是很常见的需求。以下是如何针对你提供的案例进行处理: 后端返回的数据中,按staff默认排序,但前端需要按照appeal_type和detail_appeal_type进行排序。为了实现这一需求,我们需要使用 javascript 的sort方法进行…

    2025年12月19日
    000
  • el-table 如何合并满足特定条件的数据?

    el-table 中合并具有特殊要求的数据 问题描述:在 el-table 中合并数据时,遇到了特殊的条件:只有当诉求类型和细分类型相同的情况下,诉求利用率才参与合并。 解决方案: 要解决这个问题,需要对从接口获取到的 tabledata 数据进行数据清洗,具体步骤如下: 标记特殊数据:对于首次出现…

    2025年12月19日
    000
  • 如何实现异步获取数据的相邻数据展示排序?

    相邻数据展示处理 针对异步获取的数据,进行排序处理以达到相邻数据展示的效果时,根据指定字段(如 appeal_type 和 detail_appeal_type)进行排序即可。 代码示例 为了实现对指定字段排序,可以使用 sort() 函数,并将比较函数传递给它。示例代码如下: // 先按 appe…

    2025年12月19日
    000
  • “Zenith”——一款使用 React、Tolgee 和 Tailwind CSS 的宁静冥想应用程序

    在这篇文章中,我很高兴与大家分享 zenith,这是一款冥想应用程序,旨在通过精选的舒缓声音、用户友好的界面以及对多种语言的支持来帮助用户平静和集中注意力。我将介绍该应用程序的核心功能、技术堆栈、如何设置以及在 react 中集成 tolgee。 演示 特点 舒缓的声音:用户可以从各种专为增强冥想效…

    2025年12月19日
    000

发表回复

登录后才能评论
关注微信