java - pruebas - test unitarios spring boot




¿Cómo obtener la clase de prueba de integración de Spring a autowire usando múltiples contextos? (4)

Una de mis pruebas de integración usa múltiples archivos de contexto de Spring. Parece que Spring solo se autoriza en frijoles desde el primer contexto y no el segundo. ¿Alguien sabe qué estoy haciendo mal o cómo solucionar el problema?

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:/META-INF/spring/applicationContext.xml",
        "classpath:/META-INF/spring/applicationContext-security.xml"})
@Configurable
public class UserDetailsServiceImplIntegrationTest {

    @Autowired
    UserDataOnDemand dod;
    // @Autowired does not work for this bean from applicationContext-security.xml
    UserDetailsService userDetailsService;

    @Before
    public void setup() {
        dod.init();
        // workaround for autowiring problem
        userDetailsService = (UserDetailsService)ctx.getBean("userDetailsService");
    }

    @Test
    public void testLoadUser() {
        UserDetails ud = userDetailsService.loadUserByUsername("[email protected]");
        Assert.assertEquals("[email protected]", ud.getUsername());
    }
}

Estoy usando Spring 3.0.3.

Aquí está el seguimiento de la pila cuando elimino el comentario de la línea @Autowired para UserDetailsService:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'za.co.acme.app.security.UserDetailsServiceImplIntegrationTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.security.core.userdetails.UserDetailsService za.co.acme.app.security.UserDetailsServiceImplIntegrationTest.userDetailsService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.security.core.userdetails.UserDetailsService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1064)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374)
    at org.springframework.beans.factory.wiring.BeanConfigurerSupport.configureBean(BeanConfigurerSupport.java:140)
    at org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect.configureBean(AnnotationBeanConfigurerAspect.aj:59)
    at org.springframework.beans.factory.aspectj.AbstractDependencyInjectionAspect.ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(AbstractDependencyInjectionAspect.aj:89)
    at za.co.acme.app.security.UserDetailsServiceImplIntegrationTest.(UserDetailsServiceImplIntegrationTest.java:25)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:202)

El bean está definitivamente allí ya que la búsqueda "por nombre" funciona, y es del tipo correcto.


¿Cuál es el nombre del bean para userDetailsService en su xml? Es posible que deba agregar una anotación @Qualifier con el nombre del bean y luego colocar una etiqueta <qualifier> en el contexto.

Eche un vistazo a la documentación de Spring sobre el tema.


Necesitas decirle a Spring que actúe sobre esas anotaciones. En el archivo de contexto relevante debe agregar lo siguiente:

<context:annotation-config/>

Ahora buscará esas anotaciones. Consulte la documentación de Spring sobre la configuración basada en anotaciones.

Para limitar la cantidad de clases que necesita escanear para que no escanee paquetes sin necesidad de cableado automático, agregue esto:

<context:component-scan base-package="org.example"/>

Consulte la documentación para componentes de Detección automática para obtener más información al respecto, así como los espacios de nombres XML que deberá agregar para hacer referencia a esas etiquetas.


Tengo una configuración similar y está funcionando bien para mí.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/applicationContext-struts.xml", "classpath:/applicationContext.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public abstract class BaseTests {

Mi conjetura es que el problema está en la configuración de su proyecto. ¿Utilizas Eclipse? ¿Carga los archivos de contexto desde la carpeta / bin o desde una carpeta / src? ¿Excluyó "applicationContext-security.xml" de la compilación?


Tuve el mismo problema, la solución que solucionó mi problema es cambiar la exposición del bean a través de la interfaz. (es decir) Su tipo de bean de referencia debe ser una interfaz en lugar de su clase de implementación

En su caso, cambie la referencia de clase UserDetailsService concreta con su interfaz.

Por ejemplo:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:/META-INF/spring/applicationContext.xml",
        "classpath:/META-INF/spring/applicationContext-security.xml"})
@Configurable
public class UserDetailsServiceImplIntegrationTest {

  //modified code  
  @Autowired
  IUserDetailsService userDetailsService;

    //your test cases follows

}

NOTA: Sé que esta no será una solución sensata, pero solo inténtelo, me preocupé mucho por este mismo error y finalmente cambié mi referencia y funcionó bien. Espero que resuelva tu problema.





junit