783 Stimmen

Unterschied zwischen @Mock und @InjectMocks

Was ist der Unterschied zwischen @Mock und @InjectMocks im Mockito-Framework?

19voto

Frank Jose Punkte 346

Bildbeschreibung hier eingeben

@Mock dient dazu, Mock-Instanzen zu erstellen und einzufügen, ohne Mockito.mock manuell aufrufen zu müssen. In diesem Beispiel wäre die Instanz ClassB.

Währenddessen ist @InjectMocks für das automatische Einfügen von Mock-Feldern in das getestete Objekt gedacht. In diesem Fall wäre es ClassA

16voto

Angelin Nadar Punkte 8458

Auch wenn die oben genannten Antworten abgedeckt haben, habe ich gerade versucht, winzige Details hinzuzufügen, die mir fehlen. Der Grund dafür (Das Warum).

Bildbeschreibung hier eingeben


Illustration:

Sample.java
---------------
    public class Sample{
        DependencyOne dependencyOne;
        DependencyTwo dependencyTwo;

        public SampleResponse methodOfSample(){
            dependencyOne.methodOne();
            dependencyTwo.methodTwo();

            ...

            return sampleResponse;
        }
    }

SampleTest.java
-----------------------
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassA.class})
public class SampleTest{

    @InjectMocks
    Sample sample;

    @Mock
    DependencyOne dependencyOne;

    @Mock
    DependencyTwo dependencyTwo;

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

    public void sampleMethod1_Test(){
        //Ordnen Sie die Abhängigkeiten
        DependencyResponse dependencyOneResponse = Mock(sampleResponse.class);
        Mockito.doReturn(dependencyOneResponse).when(dependencyOne).methodOne();

        DependencyResponse dependencyTwoResponse = Mock(sampleResponse.class);
        Mockito.doReturn(dependencyOneResponse).when(dependencyTwo).methodTwo();

        //Rufen Sie die zu testende Methode auf
        SampleResponse sampleResponse = sample.methodOfSample() 

        //Assert

    }
}

Referenz

15voto

serup Punkte 3258

Ein "Mocking-Framework", auf dem Mockito basiert, ist ein Framework, das es Ihnen ermöglicht, Mock-Objekte zu erstellen (in alten Begriffen könnten diese Objekte als Schüttel bezeichnet werden, da sie als Schüttel für abhängige Funktionalitäten arbeiten) Mit anderen Worten, ein Mock-Objekt wird verwendet, um das reale Objekt zu imitieren, von dem Ihr Code abhängt. Sie erstellen ein Proxy-Objekt mit dem Mocking-Framework. Durch die Verwendung von Mock-Objekten in Ihren Tests gehen Sie im Grunde von normalen Unittests zu Integrationstests über

Mockito ist ein Open-Source-Test-Framework für Java, das unter der MIT-Lizenz veröffentlicht wurde. Es ist ein "Mocking-Framework", das es Ihnen ermöglicht, schöne Tests mit einer sauberen und einfachen API zu schreiben. Es gibt viele verschiedene Mocking-Frameworks im Java-Bereich, jedoch gibt es im Wesentlichen zwei Haupttypen von Mock-Objekt-Frameworks, solche, die über Proxy implementiert werden und solche, die über Klassen-Remapping implementiert werden.

Dependency Injection-Frameworks wie Spring ermöglichen es Ihnen, Ihre Proxy-Objekte einzufügen, ohne Code zu ändern. Das Mock-Objekt erwartet, dass eine bestimmte Methode aufgerufen wird, und gibt ein erwartetes Ergebnis zurück.

Die @InjectMocks Annotation versucht, die Testobjektinstanz zu instanziieren und injiziert Felder, die mit @Mock oder @Spy annotiert sind, in private Felder des Testobjekts.

Der MockitoAnnotations.initMocks(this) Aufruf setzt das Testobjekt zurück und initialisiert die Mocks neu, also denken Sie daran, dies bei Ihrer @Before / @BeforeMethod Annotation zu haben.

11voto

tintin Punkte 5414

Ein Vorteil bei dem von @Tom erwähnten Ansatz ist, dass Sie keine Konstruktoren im SomeManager erstellen müssen und somit die Klienten daran hindern, es zu instanziieren.

@RunWith(MockitoJUnitRunner.class)
public class SomeManagerTest {

    @InjectMocks
    private SomeManager someManager;

    @Mock
    private SomeDependency someDependency; // dieser wird in someManager injiziert

    //Sie müssen den SomeManager überhaupt nicht mit dem Standardkonstruktor instanziieren 
    //SomeManager someManager = new SomeManager();    
   //Oder SomeManager someManager = new SomeManager(someDependency);

     //Tests...

}

Ob es eine gute Praxis ist oder nicht, hängt von Ihrem Anwendungsdesign ab.

11voto

dev_2014 Punkte 281

@Mock wird verwendet, um die Referenzen der abhängigen Beans zu deklarieren/mocks, während @InjectMocks verwendet wird, um die Bean zu mocken, für die der Test erstellt wird.

Zum Beispiel:

public class A{

   public class B b;

   public void doSomething(){

   }

}

Test für Klasse A:

public class TestClassA{

   @Mocks
   public class B b;

   @InjectMocks
   public class A a;

   @Test
   public testDoSomething(){

   }

}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X