
本文探讨了在mockito中,当需要对方法参数进行模拟,使其匹配一个特定集合中包含的原始类型值时,如何克服`in()`方法缺失的挑战。通过利用`argumentmatchers.intthat()`结合lambda表达式,或进一步封装成辅助方法,可以优雅地实现这一需求,提升测试代码的灵活性和可读性。
在编写单元测试时,我们经常需要使用Mockito框架来模拟对象的行为。有时,我们希望一个被模拟的方法仅在其某个参数的值包含在一个特定集合中时才执行预设的动作。例如,对于一个方法List<Integer> getValuesFor(int arg),我们可能希望当arg的值是1、2或3中的任意一个时,该方法返回特定的结果。
然而,Mockito的ArgumentMatchers和AdditionalMatchers中并没有直接提供一个类似in(1, 2, 3)的方法来匹配原始类型(如int)是否包含在一个给定的集合中。这使得直接表达此类匹配逻辑变得不直观。
为了解决这个问题,我们可以利用Mockito提供的ArgumentMatchers.intThat()方法。intThat()接受一个org.mockito.ArgumentMatcher<Integer>接口的实例,或者更简洁地,一个返回布尔值的java.util.function.Predicate<Integer>函数式接口的Lambda表达式。
以下是实现上述需求的具体步骤和示例:
立即进入“豆包AI人工智官网入口”;
立即学习“豆包AI人工智能在线问答入口”;
首先,假设我们有一个服务接口或类,其中包含以下方法:
public interface MyService {
List<Integer> getValuesFor(int arg);
}我们希望模拟MyService的一个实例,使其在getValuesFor方法接收的arg值为1、2或3时,返回特定的列表。
最直接的方法是使用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; // 确保导入 intThat
public class MockitoCollectionMatcherExample {
@Test
void testGetValuesForWithCollectionMatch() {
MyService mockObject = mock(MyService.class);
// 定义期望匹配的集合
Set<Integer> allowedArgs = Set.of(1, 2, 3);
// 使用 intThat 结合 Lambda 表达式来匹配参数
when(mockObject.getValuesFor(intThat(x -> allowedArgs.contains(x))))
.thenReturn(List.of(30, 40, 50));
// 测试匹配的参数
List<Integer> result1 = mockObject.getValuesFor(1);
System.out.println("Result for arg 1: " + result1); // 输出: [30, 40, 50]
assert(result1.equals(List.of(30, 40, 50)));
List<Integer> result2 = mockObject.getValuesFor(2);
System.out.println("Result for arg 2: " + result2); // 输出: [30, 40, 50]
assert(result2.equals(List.of(30, 40, 50)));
List<Integer> 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<Integer> 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)。
如果需要在多个测试或不同的模拟场景中重复使用相同的匹配逻辑,将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<Integer> isOneOf(Integer... values) {
Set<Integer> 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<Integer> result1 = mockObject.getValuesFor(1);
System.out.println("Result for arg 1 (helper): " + result1);
assert(result1.equals(List.of(300, 400, 500)));
List<Integer> 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内置的匹配器一样。
通过上述方法,即使Mockito没有直接提供in()这样的集合包含匹配器,我们也能通过intThat()(或其他*That()匹配器)结合Lambda表达式或辅助方法,优雅且高效地实现对原始类型参数的集合包含匹配。这使得Mockito在处理复杂参数匹配场景时依然保持了强大的能力和灵活性。
以上就是Mockito:使用intThat匹配集合中包含的原始类型参数的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号