test - java before
¿Cómo autowire el campo en @BeforeClass estático? (3)
Me parece que está intentando rellenar DB antes de las pruebas.
Me gustaría probar dos opciones:
- Si puede extraer scripts iniciales a un archivo sql (si esa es una opción para usted sin usar bean de repositorio), puede usar este enfoque y anotar su prueba con
@Sql
- Puede explorar DbUnit y aquí está el enlace al conector Spring Dbunit, que hace exactamente eso y lo ayuda a llenar la base de datos antes de las pruebas. Aquí hay un enlace github para la integración entre el marco de prueba de primavera y dbunit. Después de hacer eso, tiene
@DatabaseSetup
y@DatabaseTearDown
que harán lo que necesite en la base de datos.
Sé que esto no responde a cómo inyectar bean en @BeforeClass
estática, pero parece que está resolviendo el problema.
Actualización: Recientemente tuve el mismo problema en mi proyecto y saqué este artículo que me ayudó y creo que es una forma elegante de tratar este tipo de problema. Puede extender SpringJUnit4ClassRunner
con escucha que puede hacer la configuración a nivel de instancia con todos sus beans definidos.
@RunWith(SpringJUnit4ClassRunner.class)
public void ITest {
@Autowired
private EntityRepository dao;
@BeforeClass
public static void init() {
dao.save(initialEntity); //not possible as field is not static
}
}
¿Cómo puedo tener mi servicio inyectado ya en la clase init estática?
Para responder a esta pregunta debemos recapitular las versiones Spring 2.x.
Si desea "autowire" un bean en su clase @BeforeTest
puede usar la interfaz ApplicationContext
. Veamos un ejemplo:
@BeforeClass
public static void init() {
ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
EntityRepository dao2 = (EntityRepository) context.getBean("dao");
List<EntityRepository> all = dao2.getAll();
Assert.assertNotNull(all);
}
Lo que está sucediendo: utilizando ClassPathXmlApplicationContext
estamos creando una instancia de todos los beans contenidos en el archivo application-context.xml
.
Con context.getBean()
leemos el bean especificado (¡debe coincidir con el nombre del bean!); y luego puedes usarlo para tu inicialización.
Debería darle al bean otro nombre (¡ese es el dao2
!) De lo contrario, Spring normal "autowired" no puede funcionar en el bean predefinido.
Como nota al margen, si su prueba extiende AbstractTransactionalJUnit4SpringContextTests
, puede hacer alguna inicialización utilizando executeSqlScript(sqlResourcePath, continueOnError)
; método, por lo que no depende de una clase / método que también tiene que probar por separado.
Una solución que he estado usando para hacer que esto funcione es usar @Before
con un indicador para omitir que se esté ejecutando para cada testcase
@RunWith(SpringJUnit4ClassRunner.class)
public class BaseTest {
@Autowired
private Service1 service1;
@Autowired
private Service2 service2;
private static boolean dataLoaded = false;
@Before
public void setUp() throws Exception {
if (!dataLoaded) {
service1.something();
service2.somethingElse();
dataLoaded = true;
}
}
}