2013-03-18 2 views
8

Ich schreibe Komponententests mit Mockito und ich habe Probleme, die injizierten Klassen zu verspotten. Das Problem besteht darin, dass zwei der eingefügten Klassen vom gleichen Typ sind und nur durch ihre @Qualifier Annotation unterschieden werden. Wenn ich versuchte, einfach zu spotten SomeClass.class, wird dieser Schein nicht injiziert und dieses Objekt ist null in meinen Tests. Wie kann ich diese Objekte verspotten?Spott zwei Objekte des gleichen Typs mit 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

Wie sieht Ihr Test-Code aussehen? Ich rufe immer explizit 'Mockito.mock (SomeClass.class)' 'an, um meine Mocks zu erstellen, und halte aus meinen Unit-Tests jede Magie heraus, die durch Anmerkungen bereitgestellt wird. Sie sollten in der Lage sein, dasselbe zu tun, wenn Sie Ihre Abhängigkeiten über Konstruktor oder Setter injizieren. Gibt es einen guten Grund, warum es nicht so ist? – rcomblen

+0

Könnten Sie möglicherweise zeigen, dass diese Abhängigkeiten ohne die Verwendung von @InjectMocks injiziert werden? Ich habe mein Q aktualisiert, um zu demonstrieren, wie mein Test aufgebaut ist. – tamuren

Antwort

0

Wenn Sie keine Anmerkung verwenden, erhalten Sie so etwas wie

public class MyClass { 
    private MyDependency myDependency; 

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

und

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

Sie nur tun können, die gleiche, wenn Ihr Objekt über Konstruktor seine Abhängigkeiten angegeben eher als über Setter. Ich nehme an, dass Ihr Abhängigkeitsinjektions-Framework die Setter auf die gleiche Weise mit Annotationen versehen kann wie private Felder, aber jetzt basieren Ihre Tests nicht auf einem Framework zur Abhängigkeitsinjektion.

+0

Ich kann nicht die Verwendung der Abhängigkeitsinjektion Framework trotzen. Es ist eine Designentscheidung nicht in meinen Händen. – tamuren

9

Ich habe versucht, zwei Objekte mit dem gleichen Typ mit Mockito 1.9.5 mit JUnit zu verspotten und es funktioniert.

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

Relevante Art Informationen aus dem doc:

„Feld Injektion; Mocks wird zunächst nach der Art gelöst werden, dann, wenn es mehrere Eigenschaft des gleichen Typs, durch das Spiel der der Feldname und der Pseudoname. "

Und das eine, die Sie zu sagen scheint sollte der mock Namen für alle Ihre Mocks den Feldnamen machen übereinstimmen, wenn Sie zwei der gleichen Art haben:

„1 Hinweis: Wenn Sie Felder mit dem gleichen Typ haben (oder gleiche Löschung), ist es besser, alle mit @Mock annotierten Felder mit den passenden Feldern zu benennen, sonst könnte Mockito verwirrt werden und die Injektion wird nicht passieren. "

Vielleicht beißt dich dieser letztere?

1

Nur bestätigt, was Splonk darauf hinwies und es funktioniert so in Mockito 1.9.5, sobald ich eine der gespotteten Klassen entfernt habe, scheiterte es.

in Ihrem Fall also, stellen Sie sicher, dass Sie beide der verspottet Klassen mit dem gleichen Namen haben wie in der Klasse im Test:

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