java - starter - No se puede encontrar una @SpringBootConfiguration al hacer un JpaTest
spring-boot-starter-test example (9)
Soy nuevo en frameworks (acabo de pasar la clase) y esta es la primera vez que uso Spring Boot.
Estoy tratando de ejecutar una prueba simple de Junit para ver si mis CrudRepositories realmente funcionan.
El error que sigo recibiendo es:
Incapaz de encontrar una @SpringBootConfiguration, debe usar @ContextConfiguration o @SpringBootTest (classes = ...) con su prueba java.lang.IllegalStateException
¿Spring Boot no se configura a sí mismo?
Mi clase de prueba:
@RunWith(SpringRunner.class)
@DataJpaTest
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class JpaTest {
@Autowired
private AccountRepository repository;
@After
public void clearDb(){
repository.deleteAll();
}
@Test
public void createAccount(){
long id = 12;
Account u = new Account(id,"Tim Viz");
repository.save(u);
assertEquals(repository.findOne(id),u);
}
@Test
public void findAccountByUsername(){
long id = 12;
String username = "Tim Viz";
Account u = new Account(id,username);
repository.save(u);
assertEquals(repository.findByUsername(username),u);
}
Mi iniciador de aplicaciones Spring Boot:
@SpringBootApplication
@EnableJpaRepositories(basePackages = {"domain.repositories"})
@ComponentScan(basePackages = {"controllers","domain"})
@EnableWebMvc
@PropertySources(value {@PropertySource("classpath:application.properties")})
@EntityScan(basePackages={"domain"})
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
Mi repositorio:
public interface AccountRepository extends CrudRepository<Account,Long> {
public Account findByUsername(String username);
}
}
Además de lo que dijo Thomas Kåsene, también puede agregar
@SpringBootTest(classes=com.package.path.class)
a la anotación de prueba para especificar dónde debe buscar la otra clase si no desea refactorizar su jerarquía de archivos. Esto es lo que el mensaje de error sugiere al decir:
Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) ...
Creo que la mejor solución para este problema es alinear la estructura de carpetas de pruebas con la estructura de carpetas de la aplicación.
Tuve el mismo problema causado por la duplicación de mi proyecto desde un proyecto de estructura de carpetas diferente.
si su proyecto de prueba y su proyecto de aplicación tendrán la misma estructura, no se le pedirá que agregue anotaciones especiales a sus clases de prueba y todo funcionará como está.
De hecho, Spring Boot se configura en su mayor parte.
Probablemente ya pueda deshacerse de gran parte del código que publicó, especialmente en la
Application
.
Desearía que hubieras incluido los nombres de paquete de todas tus clases, o al menos los de
Application
y
JpaTest
.
Lo que pasa con
@DataJpaTest
y algunas otras anotaciones es que buscan una anotación
@SpringBootConfiguration
en el paquete actual, y si no pueden encontrarla allí, atraviesan la jerarquía del paquete hasta que la encuentran.
Por ejemplo, si el nombre completamente calificado para su clase de prueba era
com.example.test.JpaTest
y el de su aplicación era
com.example.Application
, entonces su clase de prueba podría encontrar la
@SpringBootApplication
(y allí, el
@SpringBootConfiguration
).
Sin embargo, si la aplicación residiera en una rama diferente de la jerarquía de paquetes, como
com.example.application.Application
,
no la
encontraría.
Ejemplo
Considere el siguiente proyecto de Maven:
my-test-project
+--pom.xml
+--src
+--main
+--com
+--example
+--Application.java
+--test
+--com
+--example
+--test
+--JpaTest.java
Y luego el siguiente contenido en
Application.java
:
package com.example;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Seguido por el contenido de
JpaTest.java
:
package com.example.test;
@RunWith(SpringRunner.class)
@DataJpaTest
public class JpaTest {
@Test
public void testDummy() {
}
}
Todo debería estar funcionando.
Si crea una nueva carpeta dentro de
src/main/com/example
llamada
app
, y luego coloca su
Application.java
dentro de ella (y actualiza la declaración del
package
dentro del archivo), ejecutar la prueba le dará el siguiente error:
java.lang.IllegalStateException: no se puede encontrar una @SpringBootConfiguration, debe usar @ContextConfiguration o @SpringBootTest (classes = ...) con su prueba
El segmento de prueba proporcionado en Spring Boot 1.4 trajo capacidades de prueba orientadas a características .
Por ejemplo,
@JsonTest proporciona un entorno Jackson simple para probar la serialización y deserialización de json.
@WebMvcTest proporciona un entorno web simulado, puede especificar la clase de controlador para la prueba e inyectar el MockMvc en la prueba.
@AutoConfigureTestDatabase(replace=NONE)
@DataJpaTest
public class TestClass{
}
@DataJpaTest preparará una base de datos integrada y proporcionará un entorno JPA básico para la prueba.
@RestClientTest proporciona un entorno de cliente REST para la prueba, especialmente RestTemplateBuilder, etc.
Estas anotaciones no están compuestas con SpringBootTest, se combinan con una serie de anotaciones
AutoconfigureXXX
y
@TypeExcludesFilter
.
Echa un vistazo a
@DataJpaTest
.
package com.example.abc;
...
@SpringBootApplication
public class ProducerApplication {
Puede agregar su anotación @AutoconfigureXXX para anular la configuración predeterminada.
package com.example.abc_etc;
...
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerApplicationTest {
Echemos un vistazo a su problema,
-
No mezcle
@DataJpaTest
y@SpringBootTest
, como se dijo anteriormente@DataJpaTest
construirá la configuración a su manera (por ejemplo, de forma predeterminada, intentará preparar un H2 incrustado) a partir de la herencia de configuración de la aplicación.@DataJpaTest
está designado para el segmento de prueba . -
Si desea personalizar la configuración de
@DataJpaTest
, lea esta entrada de blog oficial de Spring.io para este tema, (un poco tedioso). -
Divida las configuraciones en la
Application
en configuraciones más pequeñas por características, comoWebConfig
,DataJpaConfig
, etc. Una configuración con todas las funciones (web mixta, datos, seguridad, etc.) también hizo que sus pruebas basadas en el segmento de prueba fallaran. Verifique las muestras de prueba en mi muestra .
En mi caso, los paquetes eran diferentes entre las clases Aplicación y Prueba
@WebMvcTest(PostController.class)
public class PostControllerMvcTest{
@Inject MockMvc mockMvc;
}
y
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(SpringBootTestContextBootstrapper.class)
@OverrideAutoConfiguration(enabled = false)
@TypeExcludeFilters(DataJpaTypeExcludeFilter.class)
@Transactional
@AutoConfigureCache
@AutoConfigureDataJpa
@AutoConfigureTestDatabase
@AutoConfigureTestEntityManager
@ImportAutoConfiguration
public @interface DataJpaTest {}
Después de hacerlos aceptar, las pruebas se ejecutaron correctamente.
Funciona para mi
el nombre del paquete de la clase de prueba anterior se cambia al mismo que el nombre del paquete de la clase normal.
cambiar a esto
La configuración se adjunta a la clase de aplicación, por lo que lo siguiente configurará todo correctamente:
@SpringBootTest(classes = Application.class)
Ejemplo del proyecto JHipster here .
Vale la pena verificar si ha refactorizado el nombre del paquete de su clase principal anotado con
@SpringBootApplication
.
En ese caso, el caso de prueba debe estar en un paquete apropiado; de lo contrario, lo buscará en el paquete anterior.
Este fue el caso para mí.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DataJpaTest
@SpringBootTest
@AutoConfigureWebMvc
public class RepoTest {
@Autowired
private ThingShiftDetailsRepository thingShiftDetailsRepo;
@Test
public void findThingShiftDetails() {
ShiftDetails details = new ShiftDetails();
details.setThingId(1);
thingShiftDetailsRepo.save(details);
ShiftDetails dbDetails = thingShiftDetailsRepo.findByThingId(1);
System.out.println(dbDetails);
}
}
Las anotaciones anteriores funcionaron bien para mí. Estoy usando arranque de primavera con JPA.