gpt4 book ai didi

java - Mockito.when stub 被覆盖

转载 作者:行者123 更新时间:2023-11-30 07:07:43 25 4
gpt4 key购买 nike

我正在尝试按如下方式 stub 我的模拟,

when(someMock.someMethod(Matchers.<SomeInterface<MyType>> any()).thenReturn(someValue);

和,

when(someMock.someMethod(Matchers.<SomeInterface<Map<String,Boolean>>> any()).thenReturn(someOtherValue);

我注意到第二个 stub 覆盖了第一个 stub 。所以即使我调用 someMock.someMethod(new SomeInterfaceImplementation());

我也会得到 someOtherValue

我不确定这里缺少什么。我尝试查看 Mockito 文档以了解此特定用例,但没有找到任何内容。

任何帮助/指点将不胜感激。

最佳答案

由于类型删除,Mockito 将无法在运行时确定 SomeInterface<T> 实例的泛型参数传递给 someMock.someMethod .任何电话 someMethod似乎是用 SomeInterface 的实例制作的没有通用参数。

Matchers 的 JavaDoc用警告暗示这个问题(尽管它没有解释原因):

The any family methods don't do any type checks, those are only here to avoid casting in your code. If you want to perform type checks use the isA(Class) method. This might however change (type checks could be added) in a future major release.

还有一些其他辅助方法,例如 anyListOf 它似乎处理 Collections 的泛型参数,但这些只是为了方便而存在,实际上不会检查泛型类型:

Generic friendly alias to anyList(). It's an alternative to @SuppressWarnings("unchecked") to keep code clean of compiler warnings.

Any List or null.

This method don't do any type checks, it is only there to avoid casting in your code. This might however change (type checks could be added) in a future major release.

因为 any()匹配器将匹配任何对象,无论类型和通用参数如何,第二次调用 when()any()将覆盖第一个。此问题的唯一解决方案是调用 when(...)两种类型的调用仅一次,并进行某种运行时检查以确定结果应该是什么(例如,在 Answer 中传递给 thenAnswer)。

例如,假设我们要模拟以下类(真的不值得模拟,但请耐心等待):

public class SomeClass {
public <T> T getFirst(List<T> list) {
return list.get(0);
}
}

getFirst方法与您的类有相同的问题,因为使用 any/isA/anyList/anyListOf匹配器将无法区分 List<String>List<Integer> .

这是用 andAnswer 来模拟它的一种方法:

@Test
public void testGetFirst() {
SomeClass mock = mock(SomeClass.class);

when(mock.getFirst(Matchers.<List<?>>any())).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) {
List<?> list = (List<?>) invocation.getArguments()[0];

// Inspect the contents of the list to know which type to return
Object first = list.get(0);
if (first instanceof String) {
return "Z";
} else if (first instanceof Integer) {
return 1000;
} else {
return null;
}
}
});

String firstString = mock.getFirst(Arrays.asList("A", "B", "C"));
System.out.println(firstString); // prints Z

Integer firstInteger = mock.getFirst(Arrays.asList(1, 2, 3));
System.out.println(firstInteger); // prints 1000
}

这非常难看,而且根据您实际泛型类型的使用方式可能很难实现,但我相信这是解决运行时缺少泛型类型信息的唯一方法。

关于java - Mockito.when stub 被覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24615841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com