@InjectMocks
passiert vor der @Before
Annotation.
Aus diesem Grund (und other reasons) empfehle ich nicht @InjectMocks
überhaupt zu verwenden; Erstellen Sie einfach Ihre SUT Klasse in der @Before
Methode mit einem echten Konstruktor.
Diese Reihenfolge ist offensichtlich, wenn Sie Ihrer Testklasse einige Druckanweisungen hinzufügen. Ich habe alle Class1
und Class2
Sachen entfernt, da es nicht relevant ist. Sehen Sie diesen Code ausführen:
@RunWith(MockitoJUnitRunner.class)
public class DummyTest {
@Mock
private HelperClass helperclass;
@InjectMocks
private Dummy dummy;
@Before
public void start()
{
System.out.println("In @Before!");
Interface1 mockInterface = mock(Interface1.class);
when(helperclass.somefunction()).thenReturn(mockInterface);
}
@Test
public void test()
{
System.out.println("In @Test!");
}
public static class Dummy {
public final Interface1 interface1;
public final HelperClass helperclass;
@Inject
Dummy(HelperClass helperclass)
{
System.out.println("In dummy constructor!");
this.interface1 = helperclass.somefunction();
this.helperclass = helperclass;
}
}
private static class HelperClass {
Interface1 somefunction() {
return new Interface1() {};
}
}
private static interface Interface1 {
}
}
Ausgang:
In dummy constructor!
In @Before!
In @Test!
Wenn Sie darauf bestehen, es mit @Mock
tun und @InjectMocks
, Sie könnten versuchen, die answer
Argument statt:
@Mock(answer=Answers.RETURNS_MOCKS)
wird helperclass.somemethod()
einen Schein stattzurückgeben.
Ehrlich gesagt ist es nicht verwunderlich, dass es so funktioniert. Die Autoren von Mockito
wirklich nicht, wie teilweise Mocks/Stubs und ausdrücklich sagen, so in their documentation:
Wie üblich Sie gehen die partielle Mock Warnung lesen: Objektorientierte Programmierung ist weniger Komplexität der Bekämpfung durch Dividieren die Komplexität in separate, spezifische SRPy-Objekte. Wie passt partieller Schein in dieses Paradigma? Nun, es ist einfach nicht ... Partial Mock bedeutet in der Regel, dass die Komplexität auf eine andere Methode auf demselben Objekt verschoben wurde. In den meisten Fällen ist dies nicht die Art und Weise, wie Sie Ihre Anwendung entwerfen möchten.
Es gibt jedoch seltene Fälle, in denen partielle Mocks praktisch sind: Umgang mit Code, den man nicht leicht ändern kann (Interfaces von Drittanbietern, vorläufiges Refactoring von Legacy-Code usw.) Ich würde jedoch keine partiellen Mocks für neue, Test- angetriebenen & gut gestalteten Code.
helperclass
Rückkehr etwas anderes als null
zu haben, ist eine partielle Mock, und deshalb werden sie es nicht mögen.
Ich nehme an, Interface1 ist eine Klasse, die Interfaces implementieren, oder? – Koitoer
@Koitoer Keine Schnittstelle1 ist eine 'Schnittstelle'. Nicht Implementierung. Es ist analog zu "List" nicht "ArrayList" – user7