Mockito @InjectMocks战略

时间:2015-12-09 12:03:14

标签: java mocking mockito junit4

是的,我知道,有很多关于Mockito的@InjectMocks的文章,但仍有一个问题我无法解决......

我们假设我们有一个有四个成员的班级......

class A {

    public B b1;
    public B b2;
    public B b3;
    public B b4;

}

... B是一个空接口......

interface B {

}

...然后此设置将无法正确初始化:

class MyTest {

    @InjectMocks
    private A a;

    @Mock(name = "b2")
    private B b2;  // will correctly be injected into field b2

    @Mock(name = "b4")
    private B b4;  // will be injected into field b3

    @Before
    public void init() {
        MockitoAnnotations.initMocks( this );
    }

    // some test here

}

为什么呢?我调试了整件事,发现它就是这样......

  1. 搜索字段b1的正确模拟。找到两个合适类型的候选人,所以寻找名字。没有一个名字匹配。结束。 b1为空,正确。
  2. 搜索字段b2的正确模拟。找到两个合适类型的候选人,所以寻找名字。其中一个名字匹配。使用模拟“b2”正确填充b2
  3. 搜索字段b3的正确模拟。只有一个候选人(“b4”)找到合适的类型,所以使用那个。 b3错误地填充了模拟“b4”。
  4. 字段b4没有模拟,将保持为空(错误)。
  5. 所以,唯一的解决方案是总是添加一个超过需要的模拟(这样对于所有需要的模拟,总是至少有2个候选者):

    @Mock(name = "fakeyMcFakeFake")
    private B fakeyMcFakeFake;
    

    (当然,在第二次传递中,fakeyMcFakeFake将被注入字段b1,但至少其他字段将填充正确的模拟)。但这真的可以解决这个问题吗?有谁知道为什么不能更好地处理或如何更好地处理它?

    (至于用例......我有一个控制器,有各种文本框等作为成员(那些将被注入实时代码),显然它们中的许多是相同的类型但是对于每个测试我只需要少量的。)

1 个答案:

答案 0 :(得分:2)

这已在拉取请求#215中修复(请参阅release notes)。我怀疑你的代码是关于较旧版本的mockito。

虽然我喜欢powermock,但我建议设计代码的方式是使用模拟测试不依赖于powermock。

同样对于powermock,要么升级到版本1.6.4(刚刚发布); powermock github存储库存在一个问题(#14),它将依赖关系更改为mockito-core。 否则,请在声明mockito-all依赖项时排除powermockmockito-all是非maven用户(仍使用中央存储库)的依赖项。但是我不确定未来的mockito 2.x测试版是否与当前(1.6.x)的powermock版本兼容。