2016-02-10 3 views
0

У меня есть этот интерфейс сервисаКак поиздеваться в @Inject интерфейс

public interface ABC { 
    public String getAbc(); 
} 

И у меня есть этот контроллер, который использует эту службу

public class Do { 
    @Inject ABC abc; 

    public String doAbc() { 
     String a = abc.getAbc(); 
    } 
} 

В моей тестовой единицы, я хочу, чтобы иметь возможность издеваться вне этого ABC и не должны обеспечивать фактическую реализацию. Вот что работает:

public class TestDo { 
    @Mock 
    private Do do; 

    @Mock 
    private ABC abc; 

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

    @Test 
    public void testDo() { 
     when(do.doAbc()).thenCallRealMethod(); 
     do.doAbc(); 
     assertSomething... 
    } 
} 

Но то, что я не хочу делать это do.abc = abc;, от всех моих поисков, чтобы сделать @InjectMock, необходимо предоставить конкретный класс. Есть ли способ для меня использовать интерфейс, но в то же время он способен внедрить насмешливый интерфейс без необходимости раскрывать мой ABC-инъект в Do Class? Я хочу сделать ABC частной переменной и все еще в состоянии ввести интерфейс через Mockito.

ответ

2
public interface ABC { 
    public String getAbc(); 
} 

public class Do { 

    @Inject 
    ABC abc; 

    public String doAbc() { 
     System.out.println("Injected abc is " + (abc == null ? "null" : "not null")); 
     return abc.getAbc(); 
    } 

} 


public class TestDo { 
    @Mock 
    private ABC abc; 

    @InjectMocks 
    private Do ddo; 

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

    @Test 
    public void simpleTest() { 
     System.out.println(ddo.doAbc()); 
    } 

} 

выход:

Injected abc is not null 
null 
+0

Я уже пробовал это. Но do.abc имеет значение null, когда я это делаю. – Churk

+0

@Churk, протестировал его с помощью Mockito 1.9.5, JDK 1.8. Все работает. Я обновлю свой ответ на полный рабочий код. – Rustam

+0

Я перечитываю ваш код. Моя ошибка заключалась в том, что у меня был/@ InjectMocks на том, что эквивалентно ABC на моем фактическом коде, поэтому он пытался создать экземпляр интерфейса, который меня отбрасывал. И имел/@ Mock на том, что эквивалентно Do, поэтому мой издевательский и injectMocking был назад. – Churk

3

примера вы дали это идеальный случай для инъекций конструктора: Вы можете сделать зависимость частной (и даже финал, который всегда предпочтительнее, когда практическим) и по-прежнему создавать экземпляр без необходимости в рамках инъекции:

public class Do { 
    private final ABC abc; 

    @Inject 
    public Do(final ABC abc) { 
     this.abc = abc; 
    } 

    public String doAbc() { 
     String a = abc.getAbc(); 
    } 
} 
+0

Я не хочу подвергать ABC все вместе. Я хочу сделать '' '@Inject private ABC abc;' '' – Churk

+2

@Churk Ваш 'ABC' является зависимостью. Ваш класс 'Do' должен * иметь его. Использование полевой инъекции для скрытия зависимостей просто увеличивает вероятность того, что в дальнейшем что-то развалится - в дополнение к более сложному тестированию. Вся точка DI - удалить магические зависимости, сделав их явными. – chrylis

+0

Это не скрыть зависимости, но в моем реальном использовании это DataAccessService, я не хочу, чтобы кто-либо имел прямой доступ к этой службе. Вот почему я хочу, чтобы это было частным. – Churk

Смежные вопросы