Ole*_*lko 16 java unit-testing inject mockito
我很惊讶地发现,以下简单的代码示例并不适用于所有Mockito版本> 1.8.5
@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {
@Mock(name = "b2")
private B b2;
@InjectMocks
private A a;
@Test
public void testInjection() throws Exception {
assertNotNull(a.b2); //fails
assertNull(a.b1); //also fails, because unexpectedly b2 mock gets injected here
}
static class A{
private B b1;
private B b2;
}
interface B{}
}
Run Code Online (Sandbox Code Playgroud)
在javadocs(http://docs.mockito.googlecode.com/hg/latest/org/mockito/InjectMocks.html)中有一个引用:
注1:如果你有相同类型(或相同的擦除)的字段,最好用匹配的字段命名所有@Mock注释字段,否则Mockito可能会感到困惑,注入不会发生.
这是否意味着如果我有几个相同类型的字段我不能只模拟其中一个而是应该@Mock为所有相同类型的字段定义?是否已知限制,是否有任何原因尚未解决?@Mock按字段名称匹配应该是直截了当的,不是吗?
Tim*_*ppe 20
看来Mockito使用他们的JavaDoc中描述的算法
如果我理解正确,它将首先对类型进行排序(在这种情况下只有1 B)然后按名称排序(此处不做更改).最后将使用OngoingInjector接口实现注入,该实现似乎搜索第一个字段并将其注入.
由于你只定义了1个B并且模拟中有2个B字段,它将看到第一个实例与字段的匹配并停止.这是因为mocks.size() == 1在NameBasedCandidateFilter中
.因此它将停止过滤并直接注入.如果您创建多个相同类型的模拟,它们将按名称排序并相应地注入.
当我创建特定类型的多个模拟(但少于字段数)时,我能够使它工作.
@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {
@Mock(name = "b2")
private B b2;
@Mock(name = "b3")
private B b3;
@InjectMocks
private A a;
@Test
public void testInjection() {
System.out.println(this.a);
}
static class A {
private B b1;
private B b2;
private B b3;
}
interface B {
}
}
Run Code Online (Sandbox Code Playgroud)
这将正确地将b2注入a.b2并将b3注入a.b3而不是a.b1和a.b2(A中定义的前2个字段).
您可以随时在其存储库中留下GitHub问题,并对注入过滤算法进行增强或更改,以便进行查看.
| 归档时间: |
|
| 查看次数: |
8260 次 |
| 最近记录: |