web-dev-qa-db-de.com

Überschreiben eines automatisch verdrahteten Beans in Komponententests

Gibt es eine einfache Möglichkeit, eine automatisch verdrahtete Bean in bestimmten Unit-Tests leicht zu überschreiben? Es gibt nur eine einzige Bean jedes Typs in den Kompilierklassen, so dass es in diesem Fall kein Problem für die automatische Einstellung ist. Die Testklassen enthalten zusätzliche Muster. Beim Ausführen eines Komponententests möchte ich einfach eine zusätzliche Konfiguration angeben, die im Wesentlichen besagt, dass beim Ausführen dieses Verwendungstests dieser Mock anstelle der Standard-Bean verwendet wird.

Die Profile scheinen ein wenig übertrieben für das, was ich brauche, und ich bin nicht sicher, ob dies mit der Primärnotiz möglich ist, da unterschiedliche Komponententests unterschiedliche Vorstellungen haben könnten.

42
samblake

Wenn Sie einfach nur eine andere Bohne in Ihren Tests anbieten möchten, brauchen Sie keine Federprofile oder Mockito.

Mach einfach folgendes:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = { TestConfig.class })
public class MyTest
{
    @Configuration
    @Import(Application.class) // the actual configuration
    public static class TestConfig
    {
        @Bean
        public IMyService myService()
        {
            return new MockedMyService();
        }
    }

    @Test
    public void test()
    {
        ....
    }
}

HINWEIS: getestet mit Federpaket 1.3.2/Feder 4.2.4

62
teo

In Spring Boot 1.4 gibt es dafür eine einfache Möglichkeit:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { MyApplication.class })
public class MyTests {
    @MockBean
    private MyBeanClass myTestBean;

    @Before
    public void setup() {
         ...
         when(myTestBean.doSomething()).thenReturn(someResult);
    }

    @Test
    public void test() {
         // MyBeanClass bean is replaced with myTestBean in the ApplicationContext here
    }
}
39

Ich hatte ein ähnliches Problem und löste mich mit einem Mix. Ich finde dieses Problem nützlicher und wiederverwendbar. Ich habe ein Federprofil für die Tests und eine Konfigurationsklasse erstellt, die die Beans überschreibt, die ich auf sehr einfache Weise nachahmen möchte: 

@Profile("test")
@Configuration
@Import(ApplicationConfiguration.class)
public class ConfigurationTests {

    @MockBean
    private Producer kafkaProducer;

    @MockBean
    private SlackNotifier slackNotifier;

}

Auf diese Weise kann ich diese Scheinbohnen @Autowire verwenden und Mockito verwenden, um sie zu überprüfen. Der Hauptvorteil ist, dass jetzt alle Tests nahtlos die Musterbeans erhalten, ohne dass Änderungen vorgenommen werden müssen. Getestet mit:

federstiefel 1.4.2

4

Sie sollten Federprofile verwenden, um zu wissen, welche Art von Bean Sie in verschiedenen Kontexten verwenden möchten.

http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html

1
Eddú Meléndez

Wie mats.nowak kommentierte, ist @ContextConfiguration hierfür hilfreich.

Angenommen, eine übergeordnete Testklasse ist wie folgt:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring/some-dao-stuff.xml"
    ,"classpath:spring/some-rest-stuff.xml"
    ,"classpath:spring/some-common-stuff.xml"
    ,"classpath:spring/some-aop-stuff.xml"
    ,"classpath:spring/some-logging-stuff.xml"
    ,"classpath:spring/some-services-etc.xml"
})
public class MyCompaniesBigTestSpringConfig {
...

Erstellen Sie eine untergeordnete Testklasse:

package x.y.z;
@ContextConfiguration
public class MyOneOffTest extends MyCompaniesBigTestSpringConfig {
...

und in src/test/resources/x/y/z/MyOneOffTest-context.xml einfügen

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <bean id="widgetsService" class="com.mycompany.mydept.myservice.WidgetsService" primary="true" />

</beans>

Diese widgetsService-Bean überschreibt (oder ersetzt die), die in der Haupt-Konfigurations-XML (oder Java-Konfiguration) definiert ist. Weitere Informationen hierzu finden Sie unter inheritLocations Beachten Sie auch die Standarddatei -context.xml. Beispiel dafür hier . Update: Ich musste primary="true" hinzufügen, anscheinend ist es nötig.

0
user1527469