Mockito创造了不同的实例?

时间:2015-10-30 07:16:56

标签: unit-testing java-ee mockito

我有一个企业Java bean,其中有一些javax.inject.Inject注入依赖项。我还有一个测试类,它使用@Mock@Produces注释来模拟这些依赖项。一切正常,除了Mockito似乎为bean(MyDependency@50778)和测试类(MyDependency@50835)创建不同的实例,因此verify()调用总是失败,因为所有调用都发生在bean实例和检查在测试实例上完成。最有趣的部分是在持续集成服务器上测试运行正常,问题似乎与我的本地环境有关。我发现CI服务器日志与本地运行的输出之间没有显着差异。

我知道我不能在这里包含我所有的本地偏好,项目设置,日志,所以有人可以盲目地指出实际问题在这里是没有希望的。我正在寻找的是一般指导原则...我可以遵循的暗示来解决这个问题:什么可能使Mockito为我的注入依赖创建不同的实例?

编辑(代码是为了清晰起见而添加的,因为它被要求了。我不确定它是否会改变这个问题):

public class MyClass {

    @Inject
    private MyDependencyInterface myDependency; 

    public void callDependency() {
        myDependency.called();
    }
}

@RunWith(Arquillian.class)
public class MyTestClass {

    @Inject
    private MyClass myObject;

    @Inject
    private MyOtherClass myOtherObject;

    @Produces
    @Mock
    private static MyDependencyInterface dependency;

    @Before
    public void mockDependency() {
        dependency = Mockito.mock(MyDependencyInterface.class);
    }

    @Test
    public void testCallDependency() {
        myObject.callDependency();
        Mockito.verify(dependency, Mockito.atLeastOnce()).start();
    }

    @Test
    public void testOtherStuff() {
        myOtherObject.call();
        // ...
    }

    // ...
}

2 个答案:

答案 0 :(得分:0)

您正在使用@Mock注释初始化,但随后在您的@Before方法中,您正在创建另一个模拟并将其重新分配给该字段。我不熟悉Arquillian.class,但如果这是为你初始化你的模拟,那么你在@Before方法中创建第二个模拟,这将是一个与被注射。

答案 1 :(得分:0)

这不是一个真正的答案,因为我仍然无法弄清楚正在发生什么,以及如何使用旧代码和CDI,但这是我过去常用的解决方法这样:

@Before
public void mockDependency() {
    dependency = Mockito.mock(MyDependencyInterface.class);
}

成了

@Before
public void mockDependency() {
    if (dependency == null) {
        dependency = Mockito.mock(MyDependencyInterface.class);
    } else {
        Mockito.reset(dependency);
    }
    // everything else continues as before
}

这是依赖项至少初始化一次,但是在CDI获得引用后它才会被重置。引用保持不变,verify()调用在调用方法调用的同一实例上调用。每个人都很开心,except me