Как использовать 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, используя инъекцию через конструктор.


person Tobias Walter    schedule 13.05.2017    source источник


Ответы (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-метаданных должен быть в пути к классам вашего теста во время компиляции, чтобы он мог сгенерировать заглушку. Вы помещаете @Rank (1) в заглушку, чтобы гарантировать, что он будет выбран вместо исходного класса B.

Надеюсь это поможет!

person jwells131313    schedule 17.05.2017