2013-03-18 2 views
8

Я пишу модульные тесты с использованием Mockito, и у меня возникают проблемы с издевательством над введенными классами. Проблема в том, что два из введенных классов одного типа и только дифференцированы по их аннотации @Qualifier. Если я попытался просто высмеять SomeClass.class, этот макет не вводится и этот объект null в моих тестах. Как я могу издеваться над этими объектами?Стыковка двух объектов одного типа с Mockito

public class ProfileDAL { 

    @Inject 
    @Qualifier("qualifierA") 
    private SomeClass someClassA ; 

    @Inject 
    @Qualifier("qualifierB") 
    private SomeClass someClassB ; 

    //...various code, not important 
} 

@RunWith(MockitoJUnitRunner.class) 
public class ProfileDALLOMImplTest { 

    @InjectMocks 
    private ProfileDALLOMImpl profileDALLOMImpl = new ProfileDALLOMImpl(); 

    @Mock 
    private SomeClass someClassA; 
    @Mock 
    private SomeClass someClassB; 

    private SomeResult mockSomeResult = mock(SomeResult.class); 

    @Test 
    public void testSomeMethod() { 
     when(someClassA .getSomething(any(SomeArgment.class)).thenReturn(mockSomeResult); 
     Int result = profileDALLOMImpl.someTest(This isn't relevant); 
    } 

} 
+0

Как ваш тестовый код выглядит? Я всегда явно называю 'Mockito.mock (SomeClass.class)', чтобы создавать свои макеты, сохраняя вне моих юнитов все магии, предоставляемые аннотациями. Вы должны быть в состоянии сделать то же самое, если вы вводите свои зависимости через конструктор или сеттеры. Есть ли веская причина, что это не так? – rcomblen

+0

Не могли бы вы продемонстрировать инъекцию этих зависимостей без использования @InjectMocks? Я обновил свой Q, чтобы продемонстрировать, как настроен мой тест. – tamuren

ответ

0

Если вы не используете аннотацию, вы получите что-то вроде

public class MyClass { 
    private MyDependency myDependency; 

    public void setMyDependency(MyDependency myDependency){ 
     this.myDependency = myDependency; 
    } 
} 

и

import org.junit.Before; 
import org.junit.Test; 

import static org.mockito.Mockito.*; 

public class MyTest { 

    private MyClass myClass; 
    private MyDependency myDependency; 

    @Before 
    public void setUp(){ 
     myClass = new MyClass(); 
     myDependency = mock(MyDependency.class); 
     myClass.setMyDependency(myDependency); 
    } 

    @Test 
    public void test(){ 
     // Given 

     // When 

     // Then 
    } 
} 

Вы можете сделать так же, если ваш объект определили его зависимости с помощью конструктора, а чем через setter. Я предполагаю, что ваша инфраструктура инъекций зависимостей может аннотировать сеттеры так же, как вы комментируете частные поля, но теперь ваши тесты не зависят от какой-либо схемы внедрения зависимостей.

+0

Я не могу игнорировать использование рамки внедрения зависимостей. Это дизайнерское решение не в моих руках. – tamuren

9

Я попытался издеваться над двумя объектами одного типа с Mockito 1.9.5 с помощью JUnit, и он работает.

См: http://static.javadoc.io/org.mockito/mockito-core/1.9.5/org/mockito/InjectMocks.html

Соответствующая информация типа с дока:

«Поле инъекции, издевается сначала будет решено по типу, а затем, если есть несколько свойства того же типа, в матче имя поля и имя фиктивного имени. "

И это один, который, кажется, что вы должны сделать макет имя совпадает с именем поля для всех ваших издевается, когда у вас есть два одинакового типа:

«Примечание 1: Если у вас есть поля с тем же типа (или одно и то же стирание), лучше всего называть все аннотированные поля @Mock соответствующими полями, иначе Mockito может запутаться, и инъекции не произойдет ».

Возможно, этот последний кусает вас?

1

Только что подтвердил, что сказал Сплонк, и так работает в Mockito 1.9.5, как только я удалил один из издевавшихся классов, он потерпел неудачу.

Таким образом, в вашем случае, убедитесь, что у вас есть оба издевались классы с тем же именем, что и в классе в тесте:

@Mock 
private SomeClass someClassA; 
@Mock 
private SomeClass someClassB; 
Смежные вопросы