如何在 HK2 上使用 Mockito?

How to use Mockito with HK2?

我正在使用 HK2 进行依赖注入,并想在 JUnit 测试的上下文中用 Mockito-mock 替换单例对象。

最简单的设置如下:

import javax.inject.Inject;
import org.jvnet.hk2.annotations.Service;

@Service
public class A {

    @Inject
    private B b;

    public String test() {
        return b.toString();
    }

}

@Service
public class B {

    public String toString()
    {
        return "B";
    }

}

而 JUnit-Test 存根如下:

import static org.junit.Assert.*;

import javax.inject.Inject;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.jvnet.hk2.testing.junit.HK2Runner;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class MockTest extends HK2Runner {

    private B bMock = Mockito.mock(B.class);

    @Inject
    private A a;

    @Test
    public void test() {
        Mockito.when(bMock.toString()).thenReturn("Mock");
        assertEquals("Mocking worked", "Mock", a.test());
    }

}

我希望将 B 的 Mock 注入到 A 而不是真正的对象中。如何全局配置 HK2,以便为 B 的每个实例使用模拟? 我已经知道我可以通过构造函数使用注入在本地将 B 注入 A。

您是否考虑过使用 B 的 @Stub 而不是 Mock?。为此,您可以将 @Contract 添加到 B:

的实现中
@Service @Contract
public class B {

    public String toString()
    {
        return "B";
    }

}

而不是使用模拟使用 @Stub:

public class MockTest extends HK2Runner {

    @Inject
    private A a;

    @Test
    public void test() {
        assertEquals("Mocking worked", "Mock", a.test());
    }

    @Stub @Rank(1)
    public static abstract class BStub extends B {
        public String toString() {
            return "Mock";
        }

    }

}

为了使其正常工作,hk2-metadata-generator 应该在编译期间位于测试的 class 路径中,以便它可以生成存根。您将 @Rank(1) 放在存根上以确保它在原始 B class.

上被选中

希望对您有所帮助!