unitarios unitarias tutorial test pruebas framework curso spring-boot spring-test

spring-boot - tutorial - pruebas unitarias spring boot



Deshabilite la seguridad para pruebas unitarias con arranque de resorte (7)

Estoy tratando de crear un proyecto web simple de arranque de primavera con seguridad. Puedo iniciar la aplicación bien y la seguridad funciona bien. Sin embargo, tengo algunos componentes que quiero probar sin seguridad (o prueba en absoluto; no puedo hacer que la prueba funcione en absoluto).

Recibo una excepción que indica que no puede encontrar un ObjectPostProcessor y, por lo tanto, no puede abrir el contenedor.

Causado por: org.springframework.beans.factory.NoSuchBeanDefinitionException: No se ha encontrado ningún bean calificado del tipo [org.springframework.security.config.annotation.ObjectPostProcessor] para la dependencia

14:01:50.937 [main] ERROR o.s.boot.SpringApplication - Application startup failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name ''fmpdfApplication.ApplicationSecurity'': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.setObjectPostProcessor(org.springframework.security.config.annotation.ObjectPostProcessor); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.config.annotation.ObjectPostProcessor] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:320) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE] at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:103) [spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE] at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12] at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12] at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.junit.runner.JUnitCore.run(JUnitCore.java:137) [junit-4.12.jar:4.12] at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) [junit-rt.jar:na] at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) [junit-rt.jar:na] at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) [junit-rt.jar:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_45] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_45] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_45] at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_45] at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) [idea_rt.jar:na] Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.setObjectPostProcessor(org.springframework.security.config.annotation.ObjectPostProcessor); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.config.annotation.ObjectPostProcessor] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:649) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] ... 43 common frames omitted Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.config.annotation.ObjectPostProcessor] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:606) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] ... 45 common frames omitted

Ni siquiera estoy tratando de probar nada relacionado con la web o la seguridad ni nada. Solo estoy probando uno de mis componentes. Mi prueba de unidad (en groovy) es como:

@RunWith(SpringJUnit4ClassRunner) @SpringApplicationConfiguration(classes = FmpdfApplication) @ActiveProfiles(["test", "mockstore"]) class PdfUpdaterTest { @Resource PdfUpdater pdfUpdater ...

Y mis dependencias de gradle (relevantes) son:

compile("org.springframework.boot:spring-boot-starter-actuator") compile("org.springframework.boot:spring-boot-starter-security") compile("org.springframework.boot:spring-boot-starter-web") compile("org.springframework.boot:spring-boot-starter-jdbc") testCompile("org.springframework.boot:spring-boot-starter-test")

He intentado configurar management.security.enabled = false security.basic.enabled = false Pero eso no ayudó

Otro dato relevante: necesitaba personalizar la seguridad, así que seguí el patrón para:

@Configuration @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter { @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { ..

¿Es esto parte del problema? ¿Hay alguna manera de hacer que este @Lazy esté relacionado?

Actualización: si marco la prueba unitaria como @WebIntegrationTest, todo funciona, pero se inicia un servidor Tomcat incorporado. ¿Cómo puedo deshabilitar Spring Security para la unidad que prueba cosas que no son web?


Es probable que FmpdfApplication se anote con @EnableAutoConfiguration (o con @SpringBootApplication que se @EnableAutoConfiguration con @EnableAutoConfiguration ), y esto llevará a que Spring Security se recoja y configure mediante configuración automática.

Si desea ver qué se configura automáticamente, inicie su aplicación web y acceda al punto final de autoconfig (por ejemplo, http://localhost:8080/autoconfig ). Luego busque ''Seguridad'' para ver qué clases de ''Autoconfiguración'' se están detectando.

A continuación, puede deshabilitar la configuración automática de seguridad excluyendo esas clases como esta:

@EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class, ManagementSecurityAutoConfiguration.class })

Por supuesto, no querrá excluirlos para implementaciones de producción. Por lo tanto, deberá tener una clase de @Configuration separada para producción y pruebas.

Saludos,

Sam

ps También puede encontrar útil mi respuesta a la siguiente pregunta: Prueba de integración basada en el módulo Spring-Boot



Otra forma puede ser usar @ActiveProfile . Cree un archivo yml separado como application-nosecurity.yml , con el siguiente contenido:

security: ignored: /**

Ahora, anote la clase Test con @ActiveProfile("nosecurity") en el que no desea utilizar la seguridad como se muestra a continuación:

@RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) @ActiveProfile("nosecurity") public class BlaBlaTest { ## Your Test Code }


Para mí, la solución fue actualizar mis anotaciones de prueba. Reemplacé:

@SpringApplicationConfiguration(classes = { MyApplication.class }) @RunWith(SpringJUnit4ClassRunner.class)

con

@RunWith(SpringRunner.class) @SpringBootTest @ContextConfiguration(classes = MyApplication.class)


Pruebe este para deshabilitar la seguridad de arranque de primavera para probar

@AutoConfigureMockMvc (seguro = falso)

@RunWith(SpringRunner.class) @WebMvcTest(SampleController.class) @AutoConfigureMockMvc(secure = false) public class SampleControllerIntegrationTest {


Si su aplicación no era una base web pero necesita un contenedor de seguridad de Spring como dependencia y no desea las configuraciones automáticas de Spring-boot para la seguridad de Spring durante la prueba, puede agregar

@SpringBootTest(webEnvironment = WebEnvironment.NONE)

en tu clase de examen.


ACTUALIZAR PARA RESPONDER: Otra opción que aprendí recientemente si estoy usando MockMvc y AutoConfigureMockMvc para probar mis controladores, solo puedo configurar secure = false para desactivar cualquier seguridad aplicable a sus controladores.

@AutoConfigureMockMvc(secure = false)

Si no, vaya a continuación para la autenticación básica.

La excepción que obtiene es muy diferente de la que estaba obteniendo, pero si desea deshabilitar la seguridad mientras ejecuta casos de prueba, puede intentar usar perfiles y deshabilitar la seguridad básica usando propiedades para el perfil de prueba. Esto es lo que hice -

  1. Se agregó la anotación @Profile(value = {"development", "production"}) a mi implementación de WebSecurityConfigurerAdapter -

@Configuration @EnableWebSecurity @Profile(value = {"development", "production"}) public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

2. Ahora, en test/resources , cree application-test.yml para definir propiedades para el perfil de prueba y agregue esto:

# Security enable/disable security: basic: enabled: false

3. Ahora, a sus casos de prueba, agregue esta anotación para aplicar el perfil activo @ActiveProfiles(value = "test") . Así se veía mi clase:

@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration @ActiveProfiles(value = "test") @IntegrationTest({"server.port=0"}) public class SampleControllerIntegrationTest {

Hacer esto deshabilitó la seguridad de mis casos de prueba y pude acceder a las URL autenticadas. Espero que esto funcione para ti también. ¡¡¡La mejor de las suertes!!!