gpt4 book ai didi

java - Mockito @InjectMocks 不适用于相同类型的字段

转载 作者:太空狗 更新时间:2023-10-29 22:45:54 26 4
gpt4 key购买 nike

我很惊讶地发现下面的简单代码示例并不适用于所有 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{}
}

在 javadocs ( http://docs.mockito.googlecode.com/hg/latest/org/mockito/InjectMocks.html ) 中有一个引用:

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

这是否意味着如果我有多个相同类型的字段,我不能只模拟其中一个,而是应该为相同类型的所有 字段定义@Mock ?它是已知的限制吗?是否有任何原因尚未修复?按字段名称匹配 @Mock 应该很简单,不是吗?

最佳答案

Mockito 似乎使用了 their JavaDoc 中描述的算法

如果我没理解错的话,它会先按类型排序(在本例中只有 1 B),然后按名称排序(这里没有变化)。它最终将使用 the OngoingInjector interface implementation 注入(inject),它似乎在搜索第一个字段并将其注入(inject)。

由于您只定义了 1 个 B,并且 Mock 中有 B 的 2 个字段,因此它将看到第一个实例与该字段的匹配并停止。这是因为 NameBasedCandidateFilter 中的 mocks.size() == 1.因此它将停止过滤并直接注入(inject)。如果您创建多个相同类型的模拟,它们将按名称排序并相应地注入(inject)。

当我创建多个特定类型的模拟(但少于字段数)时,我能够让它工作。

@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 {
}
}

这将正确地将 b2 注入(inject) a.b2 并将 b3 注入(inject) a.b3 而不是 a.b1 和 a.b2(A 中定义的前 2 个字段)。

您始终可以在他们的存储库中留下 GitHub 问题,以增强或更改注入(inject)过滤算法以便查看。

关于java - Mockito @InjectMocks 不适用于相同类型的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29952152/

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