Как использовать Mockito с HK2?
Я использую HK2 для внедрения зависимостей и хочу заменить объект Singleton на Mockito-mock в контексте JUnit-Test.
Простейшая настройка будет выглядеть следующим образом:
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());
}
}
Я хочу, чтобы Mock для B был введен в A, а не в реальный Объект. Как я могу настроить HK2 глобально, чтобы для каждого экземпляра B использовался макет? Я уже знаю, что я мог бы внедрить B локально в A, используя инъекцию через конструктор.
1 ответ
Вы рассматривали возможность использования @Stub of B, а не 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-метаданных должен находиться в classpath вашего теста во время компиляции, чтобы он мог генерировать заглушку. Вы помещаете @Rank(1) на заглушку, чтобы убедиться, что она выбрана поверх исходного класса B.
Надеюсь это поможет!