2012-04-20 8 views
11

Ich habe eine Spring-XML-Bean-Definition, für die ich Integrationstests schreiben möchte. Die XML-Bean-Definition ist Teil eines größeren Anwendungskontexts, in dem mehrere solcher Dateien unter Verwendung von <import> enthalten sind. Innerhalb der Definition referenziere ich mehrere Beans, die von anderen Dateien kommen.Automatische Instanziierung in einem Spring-JUnit-Test

Für meinen Integrationstest möchte ich die Definition eigenständig instanziieren und Mockito Mocks für alle anderen Beans verwenden. Bis jetzt bin ich mit so etwas wie dieses:

FooIntegrationTest.java

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration 
public class FooIntegrationTest { 
    @Autowired private ClassUnderTest underTest; 
    @Autowired private MockedClass mock; 

    @Test 
    public void testFoo() { 
    } 
} 

FooIntegrationTest-context.xml

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://www.springframework.org/schema/c" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 
    <import resource="part-to-test.xml" /> 

    <bean id="mockedClassReferencedByName" class="org.mockito.Mockito" factory-method="mock" c:classToMock="SomeMockedClass" /> 
    <bean class="org.mockito.Mockito" factory-method="mock" c:classToMock="OtherMockedClassReferencedByType" /> 
    <bean class="org.mockito.Mockito" factory-method="mock" c:classToMock="MockedClass" /> 
    ... 
</beans> 

Ich möchte das ziemlich langweilig spöttischen Abschnitt automatisieren : Im Idealfall möchte ich, dass alle Beans, die nicht im Anwendungskontext gefunden werden, automatisch mokiert werden. Die part-to-test.xml verwendet @Autowired sowie Beans, die mithilfe von Namensreferenzen festgelegt werden. Ich verwende nur XML-Bean-Definitionsdateien und verwende weder Klassen noch @Component Annotationen.

Ich habe in @ContextConfiguration(loader=...) untersucht, wie man einen benutzerdefinierten Kontextlader verwendet, aber ich habe noch keinen passenden Erweiterungspunkt dafür gefunden. Sprinockito scheint dieses Problem nicht zu lösen.

Gibt es ein anderes Projekt, das dieses Problem bereits löst? Wenn nicht, wo würde ich Spring verlängern, um die Mocks automatisch zu erstellen?

+0

Hast du die Mockito @InjectMocks Annotation ausprobiert? Inwiefern entspricht es Ihrer Anforderung? –

+0

@DavidWallace '@ InjectMocks' funktioniert sehr gut für Komponententests, d. H. Testet eine bestimmte Klasse, in der der Test gespottete Objekte verwendet. Ich möchte jedoch alle Objekte vortäuschen, auf die in einer Spring-Bean-Definition verwiesen wird. Dies bedeutet, dass ich den Spring-Anwendungskontext mit (möglicherweise genannten) Mocks füllen muss - mir ist nicht bewusst, wie "@ InjectMocks" dabei hilft. –

+0

OK, ich werde darüber noch etwas nachdenken. –

Antwort

3

Hier ist ein short article with a code example. Eine BeanDefinitionRegistryPostProcessor Implementierung generiert ein Mock-Objekt für jede fehlende Bean-Definition. Die Generierung erfolgt mit einem MocksFactory, hier ist an example for such a factory.

+0

Diese Antwort war der richtige Ausgangspunkt für die Lösung des Problems: Die Verwendung eines 'BeanDefinitionRegistryPostProcessor' ermöglicht es, die Bean-Definitionen auf fehlende Beans zu prüfen. Ich habe das Codebeispiel erweitert, um auch auf Beans zu achten, die unter Verwendung von Setter injiziert werden, aber eine solche Erweiterung ist eher trivial. –

+0

Die zweite Verbindung ist tot. RUHE IN FRIEDEN. alter Artikel –

2

Nur falls jemand noch Interesse an dieser Frage ist, habe ich den Code in die von Yves Martin mit Vererbungs erwähnten Artikel erweitert, die Unterstützung für @Inject, etc ... und schuf ein Github-Projekt hier: https://github.com/rinoto/spring-auto-mock