2012-09-21 13 views
8

Mit Spring 3.1.2, JUnit 4.10.0, und ziemlich neu in beiden Versionen. Ich habe das Problem, dass ich die Annotation-basierte Autowirkung nicht funktionieren kann.Autowinding funktioniert nicht im Frühjahr 3.1.2, JUnit 4.10.0

Unten sind zwei Beispiele, die keine Anmerkungen verwenden, die gut funktioniert. Und der zweite mit Annotation, die nicht funktioniert, und ich finde den Grund nicht. Ich habe die Samples von spring-mvc-test ziemlich genau verfolgt.

Arbeiten:

package com.company.web.api; 
// imports 

public class ApiTests { 

    @Test 
    public void testApiGetUserById() throws Exception { 
     ApplicationContext ctx = new ClassPathXmlApplicationContext("/com/company/web/api/ApiTests-context.xml"); 
     UserManagementService userManagementService = (UserManagementService) ctx.getBean("userManagementService"); 
     ApiUserManagementController apiUserManagementController = new ApiUserManagementController(userManagementService); 
     MockMvc mockMvc = standaloneSetup(apiUserManagementController).build(); 

     // The actual test  
     mockMvc.perform(get("/api/user/0").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); 
    } 
} 

Failing, weil userManagementService null ist, nicht autowired bekommen:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration  // should default to ApiTests-context.xml in same package 
public class ApiTests { 

    @Autowired 
    UserManagementService userManagementService; 

    private MockMvc mockMvc; 

    @Before 
    public void setup(){ 
     // SetUp never gets called?! 
    } 

    @Test 
    public void testGetUserById() throws Exception { 

     // !!! at this point, userManagementService is still null - why? !!!  

     ApiUserManagementController apiUserManagementController 
      = new ApiUserManagementController(userManagementService); 

     mockMvc = standaloneSetup(apiUserManagementController).build(); 

     // The actual test 
     mockMvc.perform(get("/api/user/0").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); 
    } 
} 

Beachten Sie, dass beide Testklassen oben sollte die gleiche Kontextkonfiguration verwenden, und Der userManagementService ist dort definiert.

ApiTests-context.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xmlns:jee="http://www.springframework.org/schema/jee" 
     xsi:schemaLocation=" 
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
      http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd 
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
     <property name="driverClassName" value="com.mysql.jdbc.Driver"/> 
     <property name="url" value="jdbc:mysql://localhost:3306/mydb?useUnicode=true&amp;characterEncoding=utf8"/> 
     <property name="username" value="user"/> 
     <property name="password" value="passwd"/> 
    </bean> 

    <!-- Hibernate SessionFactory --> 
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" 
      p:dataSource-ref="dataSource" p:mappingResources="company.hbm.xml"> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
       <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> 
       <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop> 
      </props> 
     </property> 
     <property name="eventListeners"> 
      <map> 
       <entry key="merge"> 
        <bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/> 
       </entry> 
      </map> 
     </property> 
    </bean> 

    <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --> 
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" 
      p:sessionFactory-ref="sessionFactory"/> 

    <!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= --> 

    <context:annotation-config/> 
    <tx:annotation-driven/> 
    <context:mbean-export/> 

    <!-- tried both this and context:component-scan --> 
    <!--<bean id="userManagementService" class="com.company.web.hibernate.UserManagementServiceImpl"/>--> 
    <context:component-scan base-package="com.company"/> 

    <!-- Hibernate's JMX statistics service --> 
    <bean name="application:type=HibernateStatistics" class="org.hibernate.jmx.StatisticsService" autowire="byName"/> 

</beans> 

und die UserManagementService (Interface) sowie UserManagementServiceImpl hat die @Service Annotation.

Zwei kleinere Fragen/Beobachtungen: setup() wird nie aufgerufen, obwohl es die Annotation @Before hat. Außerdem habe ich bemerkt, dass meine Testmethoden nicht ausgeführt/erkannt werden, wenn sie nicht mit dem Namen 'test' beginnen, was bei allen Spring-mvc-Test Samples, die ich gesehen habe, nicht der Fall ist.

pom.xml:

<dependency> 
     <groupId>org.junit</groupId> 
     <artifactId>com.springsource.org.junit</artifactId> 
     <version>4.10.0</version> 
     <scope>test</scope> 
    </dependency> 

enter image description here

Update:

Das Problem tritt nur auf, wenn ich die Tests von Maven laufen; Es ist in Ordnung, wenn ich den Test von meiner IDE (IntelliJ IDEA) aus starte.

 <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-surefire-plugin</artifactId> 
      <version>2.12.3</version> 
      <configuration> 
       <includes> 
        <include>**/*Tests.java</include> 
       </includes> 
      </configuration> 
     </plugin> 
+0

Was passiert, wenn man die Anmerkung Stil mit einer expliziten Namen Konfigurationsdatei '@ContextConfiguration (" Classpath verwenden: com/Unternehmen/web/api/ApiTests -context.xml ")' – Ralph

+2

posten Sie bitte den vollständigen Kontext. posten Sie auch Ihren Pom, weil es sich anhört, als würden Sie junit 3 irgendwie benutzen? – MikePatel

+0

@Ralph Versuchte es schon, keinen Unterschied. @ContextConfiguration (locations = {"Klassenpfad: Firma/com/web/api/ApiTests-context.xml"}) –

Antwort

6

Autowiring wird nicht ausgeführt, es sei denn, Sie führen einen Komponentenscan durch.

Warum haben Sie es in Ihrem Code auskommentiert?

<!--<context:component-scan base-package="com.company"/>--> 

Auch re: junit. Wenn Sie in Eclipse sind, können Sie einfach in die Abhängigkeitsstruktur des Pom gehen und auf Junit filtern. Überprüfen Sie, ob Sie tatsächlich diese Version verwenden und keinen älteren Junit einbinden.

Edit: Ok Ich habe gerade Ihre Konfiguration überprüft und konnte es auf dieser Seite arbeiten.Meine einzige Vermutung kann sein, dass Sie es irgendwie mit einem schlechten Testläufer laufen lassen, der es verursacht, das falsche junit zu benutzen.

Bearbeiten 2 (Gelöst): So stellt sich heraus, dass das Problem liegt daran, dass Sie eine benutzerdefinierte Version von Junit verwenden. Surefire sucht nach der bereitgestellten Junit-Bibliothek und kann sie nicht finden. Als Ergebnis wird standardmäßig junit 3 verwendet, was dazu führt, dass Ihre App das Laden der Konfiguration überspringt.

Sie können explictly den benutzerdefinierten Anbieter wie

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-surefire-plugin</artifactId> 
    <version>2.12.3</version> 
    <dependencies> 
     <dependency> 
     <groupId>org.apache.maven.surefire</groupId> 
     <artifactId>surefire-junit47</artifactId> 
     <version>2.12.3</version> 
     </dependency> 
    </dependencies> 
    </plugin> 

spezifizieren Aber ich habe festgestellt, dass es nicht gut mit benutzerdefinierten repos funktioniert. Wenn möglich, würde ich vorschlagen, die Standardversion von junit zu verwenden.

+0

Ich hatte sowohl den component-scan getestet, als auch die Bean von Hand hineingegeben. Wäre das nicht dasselbe? Aber wie auch immer, keiner von beiden funktioniert, auch wenn ich den component-scan benutze. Ich bin nicht in Eclipse, ich bin in IntelliJ IDEA. Es gibt auch eine Abhängigkeitsbaumstruktur, und sie zeigt mir org.junit: com.springsource.org.junit: 4.10.0 –

+0

Ich habe die obigen Fragen/codes erneut in component-scan geändert (nicht mehr auskommentiert). Wie gesagt, das habe ich auch schon mal ausprobiert, aber immer noch keinen Erfolg). –

+0

Ich benutze SpringJUnit4ClassRunner - meinst du das? Es ist die, die sie überall verwenden http://rstyanyanche.github.com/spring-31-and-mvc-test/#26 –

0

Versuchen Sie spezifische Kontextkonfiguration, z.

@ContextConfiguration(locations = {"/file1.xml", "/file2.xml" }) 

(nur zeigen, wie sich dies mit mehreren Dateien bei Bedarf verwendet werden - man kann genug sein)

Edit: Sie haben AutowiredAnnotationBeanPostProcessor aktiviert wie hier erwähnt? http://www.mkyong.com/spring/spring-auto-wiring-beans-with-autowired-annotation/

+0

Versuchte es, kein Unterschied, siehe aktualisierte Frage oben. –

0

Ich hatte das gleiche Problem. Mein @Autowire würde in meiner IDE (SpringSource STS) funktionieren, aber den Anwendungskontext nicht laden, wenn ich Maven zum Erstellen über die Befehlszeile verwendete.

Das Problem war mit meinen Abhängigkeiten in der pom.xml. Ich habe die Spring-Version von JUnit verwendet, die den Fehler verursacht hat. Ich denke, das ist die Ursache des ursprünglichen Posts. Ich musste kein Maven-Plugin codieren, damit es funktioniert.

Ich änderte

<dependency> 
    <groupId>org.junit</groupId> 
    <artifactId>com.springsource.org.junit</artifactId> 
    <version>4.7.0</version> 
</dependency> 

zu

<dependency> 
    <groupId>junit</groupId> 
    <artifactId>junit</artifactId> 
    <version>4.10</version> 
</dependency> 
Verwandte Themen