我对此感到困惑(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() ));
当然,getFFRD
中的方法IndexManager
会返回私有字段
private Collection<IndexableField> fieldsFromRetrievedDocument;
IndexManager
中还有另一个私有字段:
private Collection<Closeable> closeableComponents;
第一个记录的行为您提供有效的哈希码。
最后一行显示
#fFRD null
当我去检查closeableComponents
的值时,我发现它的哈希码确实是注入的模拟Collection
的哈希码。
然后我尝试在IndexManager
中交换这些字段的声明位置:没有变化。
这里的@Mock
行似乎是1)完全忽略了通用类,2)因为我不明白的原因而优先于Collection<Closeable>
锁定closeableComponents
。
稍后
哇,疯狂的东西:我刚刚将字段xcloseableComponents
的名称更改为fieldsFromRetrievedDocument
。现在,模拟的领域确实在做我想要的,即模仿领域Collection<anything>
。
我的临时结论自然就是Mockito按字母顺序使用它找到的@Mock(name="fieldsFromRetrievedDocument")
private Collection<?> mockedFieldsFromRetrievedDocument;
类型的第一个字段名称!据推测,相同的选择过程适用于其他情况,其中有相同的&#34;相同的&#34;类型。只是用Google搜索没有成功:有人知道这是否记录在某处?
以后仍然
根据杰夫鲍曼的建议,我改变了这样的事情:
Collection<?>
...这是类中字段的确切拼写,正确的情况。但它仍然在注入错误的name
作为模拟。然后......
我从Mockito 1.10变为最新的2.3.0:问题解决了!一个警示故事,<!DOCTYPE html>
<!--Website made by William Stinson, 2016, Unsolicitedly.-->
<html>
<head>
<style>
.center {
text-align: center;
}
</style>
</head>
<body>
<div class="center">
<a href="http://www.gifford.org">
<img src="http://www.myhopesanddreams.com/william/giffordlogo.png" draggable="false" alt="logo" />
</a>
<br>
<img src="myhopesanddreams.com/Untitled 3.png" height="100" draggable="false">
<iframe src="https://docs.google.com/a/gifford.org/forms/d/e/1FAIpQLSeAojv3USFoCWLpHJeIoSEiOydke0dKV3wmS-EWrr4-qbxryw/viewform?embedded=true" width="1300" height="1000" frameborder="3" marginheight="0" marginwidth="0">Loading...</iframe>
<h1>Created for The Gifford School by William Stinson</h1>
</div>
</body>
</html>
属性完全记录在1.10的Javadoc API中......!
答案 0 :(得分:2)
@InjectMocks
documentation描述的行为可能没有您喜欢的记录或确定性:
Property setter injection ; mocks将首先按类型解析(如果单个类型匹配注入将发生,无论名称如何),那么,如果有多个相同类型的属性,则通过匹配属性名称和模拟名称。
注意1:如果您拥有相同类型(或相同的删除)的属性,最好使用匹配的属性命名所有@Mock带注释的字段,否则Mockito可能会感到困惑注射不会发生。
这是有道理的,因为字段的泛型类型被删除 - 在运行时不可读 - 并且因为Java的反射方法getDeclaredFields
和getDeclaredMethods
被返回{{3 }}。匹配名称是首选,其他一切都是未定义的行为,您的重命名恰好操纵您的优势;不要指望这种行为。
上面命名模拟的概念是指在"not in any particular order"上使用name
属性。