2013-03-18 29 views
8

Piszę testy jednostkowe za pomocą Mockito i mam problemy z kpieniem z wstrzykniętych klas. Problem polega na tym, że dwie z wtryskiwanych klas są tego samego typu i różnicowane tylko przez ich adnotację @Qualifier. Jeśli próbowałem po prostu wyśmiewać SomeClass.class, to nie wstrzykuje się tego mocku, a ten obiekt to null w moich testach. Jak mogę kpić z tych obiektów?Kpiny z dwóch obiektów tego samego typu z 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

Jak działa kod testowy wygląda? Zawsze jawnie nazywam 'Mockito.mock (SomeClass.class)', aby tworzyć moje mocks, utrzymując z mojej jednostki testy magii dostarczonej przez adnotacje. Powinieneś być w stanie zrobić to samo, jeśli wstrzykniesz swoje zależności za pomocą konstruktora lub setera. Czy istnieje dobry powód, dla którego tak nie jest? – rcomblen

+0

Czy mógłbyś zademonstrować wstrzykiwanie tych zależności bez użycia @InjectMocks? Zaktualizowałem swoje Q, aby pokazać, jak mój test jest skonfigurowany. – tamuren

Odpowiedz

0

Jeśli nie używać adnotacji, masz coś

public class MyClass { 
    private MyDependency myDependency; 

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

i

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 
    } 
} 

Można zrobić tak samo, jeśli obiekt został określony poprzez jego zależności konstruktora raczej niż za pomocą settera. Przypuszczam, że twoja struktura wtrysku zależności może adnotować seterów w ten sam sposób, w jaki przypisujesz prywatne pola, ale teraz twoje testy nie opierają się na żadnej strukturze wtrysku zależności.

+0

Nie mogę przeciwstawić się za pomocą schematu wtrysku zależności. To decyzja projektowa nie w moich rękach. – tamuren

9

Próbowałem kpić z dwóch obiektów tego samego typu z Mockito 1.9.5 przy użyciu JUnit i to działa.

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

Istotne Informacje typ z Doc:

„Pole wtrysk; mocks najpierw zostanie rozwiązany według typu, a następnie, jeśli istnieje kilka własność tego samego typu, przez mecz nazwę pola i fałszywą nazwę. "

A ten, który zdaje się mówić należy dokonać nazwa mock dopasować nazwę pola dla wszystkich mocks gdy masz dwa tego samego typu:

„Uwaga 1: Jeżeli masz pola z tego samego typu (lub to samo wymazanie), lepiej jest nazwać wszystkie pola oznaczone adnotacjami z pasującymi polami, w przeciwnym razie Mockito może się pomylić i nie nastąpi zastrzyk. "

Być może ten drugi cię gryzie?

1

Właśnie potwierdziłem, co Splonk wskazał i działa w ten sposób w Mockito 1.9.5, jak tylko usunąłem jedną z wyśmianych klas, to się nie udało.

Więc w twoim przypadku, upewnij się, że oba szydzili klas o tej samej nazwie, jak w klasie w swoim teście:

@Mock 
private SomeClass someClassA; 
@Mock 
private SomeClass someClassB; 
Powiązane problemy