MOCKITO-哪些规则控制着类似收集类模拟的注入



我只是对此感到困惑(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() ));

自然地,IndexManager中有一种方法getFFRD返回私有字段

private Collection<IndexableField> fieldsFromRetrievedDocument;

IndexManager中还有另一个私人字段:

private Collection<Closeable> closeableComponents;

第一条记录线为您提供有效的障碍。
最后一行说

#ffrd null

然后,当我去检查closeableComponents的值时,我发现它的哈希码确实是注射的模拟Collection

然后,我尝试在IndexManager中交换这些字段的声明的位置:无更改。

看来,这里的@Mock行是1)完全忽略了通用类,而2)由于我不了解的原因而不是另一个锁定的Collection<Closeable>

哇,疯狂的东西:我只是将字段closeableComponents的名称更改为xcloseableComponents。现在,模拟的领域确实在做我想做的事,即嘲笑字段fieldsFromRetrievedDocument

自然而然地,我的临时结论是,Mockito使用了Collection<anything>类型的第一个字段名称……按字母顺序排列!大概相同的选择过程适用于其他"相同"类型的一个以上字段的其他情况。只是在没有成功的情况下对此进行了搜索:有人知道是否在某个地方记录了这一点?

后来仍然

按照杰夫·鲍曼(Jeff Bowman)的建议,我更改了类似的事情:

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

...这是班级中字段的确切拼写。但是它仍然将错误的Collection<?>注射为模拟。然后...

我从Mockito 1.10更改为最新的2.3.0:解决问题!一个警示性的故事,因为name属性已在1.10的Javadoc API中完全记录下来...!

@InjectMocks文档描述了这种行为,这可能比您喜欢的文献或确定性较低:

属性设置器注入;模拟将首先通过类型解决(如果单个类型的匹配注入将无论名称如何),那么,如果有几种类型的属性,则通过属性名称和模拟名称的匹配。

注意1:如果您具有具有相同类型(或相同擦除)的属性,则最好将所有@mock注释的字段命名为具有匹配属性发生。

这是一定有意义的,因为该字段的通用类型被删除(在运行时不可读取),并且因为Java的反射方法getDeclaredFieldsgetDeclaredMethods返回了"任何特定顺序"。匹配名称是首选的,其他一切都是未定义的行为,您的重命名偶然会为您的优势操纵;不要指望这种行为。

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

相关内容

  • 没有找到相关文章

最新更新