gpt4 book ai didi

java - Mockito - 什么规则管理类似 Collection 类的模拟注入(inject)?

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

我只是对此感到困惑(Mockito 1.10):

@Rule
public MockitoRule rule = MockitoJUnit.rule();

@Mock
private Collection<IndexableField> mockedFieldsFromRetrievedDocument;

@Spy
@InjectMocks
private IndexManager injectedSpyIM = new IndexManager();

@Test
public void numberOfLDocsShouldBePrintedOutWithEachHitLine() throws Exception{

LOGGER.info( String.format( "# A: %d", mockedFieldsFromRetrievedDocument.hashCode() ));
LOGGER.info( String.format( "# fFRD %s", injectedSpyIM.getFFRD() ));

自然有方法getFFRDIndexManager它返回私有(private)字段

private Collection<IndexableField> fieldsFromRetrievedDocument;

IndexManager 中还有另一个私有(private)字段:

private Collection<Closeable> closeableComponents;

第一行记录为您提供有效的哈希码。
最后一行表示

# fFRD null

当我检查 closeableComponents 的值时我发现它的哈希码确实是注入(inject)的模拟的哈希码 Collection .

然后我尝试交换 IndexManager 中这些字段的声明位置。 :没有变化。

看来@Mock这里的行是 1) 完全忽略通用类和 2) 锁定 Collection<Closeable>由于我不明白的原因,优先于另一个......

稍后

哇,疯狂的东西:我刚刚更改了字段的名称 closeableComponentsxcloseableComponents 。现在模拟的字段确实正在做我想要的事情,即模拟字段 fieldsFromRetrievedDocument .

很自然,我的临时结论是 Mockito 使用 Collection<anything> 类型的第一个字段名称。它发现......按字母顺序排列!据推测,相同的选择过程也适用于存在多个“相同”类型字段的其他情况。只是用谷歌搜索了一下,但没有成功:有人知道这是否记录在某处吗?

稍后

按照 Jeff Bowman 的建议,我做了如下更改:

@Mock(name="fieldsFromRetrievedDocument")
private Collection<?> mockedFieldsFromRetrievedDocument;

...这是类中字段的精确拼写(大小写正确)。但仍然注入(inject)错误Collection<?>作为模拟。然后...

我从Mockito 1.10换到最新的2.3.0:问题解决了!一个警示故事,其中 name属性在 1.10 的 Javadoc API 中有完整记录...!

最佳答案

@InjectMocks documentation 描述了行为,其记录或确定性可能比您希望的要少:

Property setter injection; mocks will first be resolved by type (if a single type match injection will happen regardless of the name), then, if there is several property of the same type, by the match of the property name and the mock name.

Note 1: If you have properties with the same type (or same erasure), it's better to name all @Mock annotated fields with the matching properties, otherwise Mockito might get confused and injection won't happen.

这是有道理的,因为该字段的通用类型被删除——在运行时不可读——并且因为 Java 的反射方法 getDeclaredFieldsgetDeclaredMethods 返回 "not in any particular order" 。匹配的名称是首选,其他一切都是未定义的行为,您的重命名恰好可以对您有利;不要指望这种行为。

上面命名模拟的概念是指在 @Mock annotation 上使用 name 属性。

关于java - Mockito - 什么规则管理类似 Collection 类的模拟注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41079432/

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