2012-09-21 20 views
8

Usando Spring 3.1.2, JUnit 4.10.0, y bastante nuevo en ambas versiones. Tengo el problema de que no puedo hacer funcionar el autoenlace basado en anotaciones.El autocableado no funciona en Spring 3.1.2, JUnit 4.10.0

A continuación hay dos muestras, la que no usa anotaciones, que funciona bien. Y el segundo uso de la anotación, que no funciona, y no encuentro el motivo. Seguí las muestras de spring-mvc-test prácticamente.

Trabajando:

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()); 
    } 
} 

A falta, porque userManagementService es nulo, no conseguir autowired:

@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()); 
    } 
} 

Tenga en cuenta que ambas clases de prueba anteriormente deben utilizar la misma configuración de contexto y el userManagementService se define allí.

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> 

y la UserManagementService (interfaz), así como UserManagementServiceImpl tiene la anotación @Service.

Dos preguntas/observaciones menores: setup() nunca se llama, a pesar de que tiene la anotación @Antes de anotar. Además, noté que mis métodos de prueba no se ejecutan/reconocen si no comienzan con el nombre 'prueba', que no es el caso sin embargo con todas las muestras de spring-mvc-test que vi.

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

Actualización:

El problema sólo se produce cuando corro las pruebas de experto; Está bien cuando ejecuto la prueba desde mi IDE (IntelliJ IDEA).

 <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

Qué ocurre si se utiliza el estilo de anotación con un archivo de configuración llamado 'explicite @ContextConfiguration (" ruta de clases: com/empresa/web/API/ApiTests -context.xml ")' – Ralph

+2

publique el contexto completo por favor. también publica tu pom porque parece que estás usando junit 3 de alguna manera? – MikePatel

+0

@Ralph Ya lo probé, no hay diferencia. @ContextConfiguration (locations = {"classpath: company/com/web/api/ApiTests-context.xml"}) –

Respuesta

6

El autoenrutamiento no se realizará a menos que realice un escaneo de componentes.

¿Por qué lo ha comentado en su código?

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

También re: junit. Si estás en eclipse, puedes ir a la vista de árbol de dependencias del pom y filtrar en junit. Comprueba que realmente estás usando esa versión y que no estás atrapando en un momento anterior.

Editar: Ok, acabo de comprobar su configuración y pude hacer que funcione de este lado.Mi única conjetura es que de alguna manera lo estás ejecutando con un mal corredor de prueba que está causando que use el junit incorrecto.

Edit 2 (SOLUCIONADO): Entonces resulta que el problema se debe a que está utilizando una versión personalizada de junit. Surefire busca la biblioteca junit provista y no puede encontrarla. Como resultado, el valor predeterminado es junit 3, que es lo que hace que su aplicación omita la carga de la configuración.

explicitamente Se puede especificar el proveedor personalizado como

<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> 

pero he encontrado que no funciona bien con las cesiones temporales personalizados. Si es posible, sugeriría usar la versión estándar de junit.

+0

Probé tanto el escaneo de componentes como el frijol manualmente. ¿No haría eso lo mismo? Pero de todos modos, ninguna de las dos cosas funciona, también cuando uso el componente-scan. No estoy en Eclipse, estoy en IntelliJ IDEA. También hay un árbol de dependencias, y me está mostrando org.junit: com.springsource.org.junit: 4.10.0 –

+0

He cambiado las preguntas/el código anterior a la exploración de componentes (no comentada más) de nuevo. Como mencioné, ya lo intenté antes, pero todavía no tuve éxito). –

+0

Uso SpringJUnit4ClassRunner - ¿lo dices en serio? Es el que utilizan en todas partes http://rstoyanchev.github.com/spring-31-and-mvc-test/#26 –

0

Pruebe la configuración de contexto específica, p.

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

(acaba de mostrar cómo se puede utilizar con varios archivos cuando sea necesario - uno puede ser suficiente)

Editar: ¿ha permitido AutowiredAnnotationBeanPostProcessor como se ha mencionado aquí? http://www.mkyong.com/spring/spring-auto-wiring-beans-with-autowired-annotation/

+0

Lo intenté, no hay diferencia, mira la pregunta actualizada arriba. –

0

Tuve este mismo problema. Mi @Autowire funcionaría dentro de mi IDE (SpringSource STS) pero no cargaría el contexto de la aplicación cuando estaba usando Maven para compilar desde la línea de comandos.

El problema estaba en mis dependencias en el pom.xml. Estaba usando la versión Spring de JUnit que causó el error. Creo que esta es la causa raíz de la publicación original. No tuve que codificar ningún plugin de Maven para que funcionara.

me cambió

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

a

<dependency> 
    <groupId>junit</groupId> 
    <artifactId>junit</artifactId> 
    <version>4.10</version> 
</dependency> 
Cuestiones relacionadas