Ich möchte eine Autowired-Klasse eines Diensts in meiner Spring-Start-App durch eine mokierte Implementierung dieser Klasse ersetzen, die ich speziell zum Testen erstellt habe.Verwenden von @InjectMocks zum Ersetzen von @Autowired-Feld durch eine mokierte Implementierung
Ich habe mich dafür entschieden, diese mockige Implementierung zu erstellen, weil das Verhalten dieser Klasse zu kompliziert ist, um Mockito zu verspotten, da es mehrere andere Mocks selbst benötigt.
Ich bin nicht in der Lage herauszufinden, wie diese gespottete Implementierung in den Dienst injiziert werden.
Hier ist ein minimales Beispiel für die Situation:
@Service
public class ServiceIWantToTestImpl implements ServiceIWantToTest{
@Autowired
ComplicatedDependency complicatedDependency;
@Override
public void methodUsingDependency(){
String string = complicatedDependency.doSomething();
System.out.println(string);
}
}
public class MockComplicatedDependency implements ComplicatedDepencency{
public MockComplicatedDependency(...){
// Inject other mocked objects into this mock
}
public String doSomthing(){
// This would be a mocked version of this function for testing
return "test";
}
}
@RunWith(MockitoJUnitRunner.class)
public class TestingTheService(){
@InjectMock
private static ServiceIWantToTest serviceIWantToTest = new ServiceIWantToTestImpl();
@Mock
ComplicatedDependency mockComplicatedDependency;
@BeforeClass
public static void init(){
mockComplicatedDependency = new MockComplicatedDependency(...);
}
@Test
public void testAttempt(){
serviceIWantToTest.methodUsingDependency(); // This method calls complicatedDependency.doSomething() which does not run the mocked version in MockComplicatedDependency which I wanted to inject, and would always return null instead of the "test" string I put in this example.
}
}
Ich habe versucht mit @Spy wie Sie vorgeschlagen und es funktioniert super. Vielen Dank! Ich möchte nicht wirklich einen Konstruktor nur zum Testen einführen, ich möchte Spring die Dependency-Injektion in der Anwendung behandeln lassen. –
Eigentlich ist die Constructor-Level-Injektion der empfohlene Ansatz, Feld-Level-Injektion wird im Allgemeinen abgeraten –
Wie schon von @Milos erwähnt, hat Spring schon seit einem Jahrzehnt die Konstruktor-Injektion empfohlen: http://spring.io/blog/2007/07/11/setter-injection-versus-constructor-injection-and-the-use-of-required /. Niemand sollte mehr Feldinjektionen verwenden. – jhyot