Estoy ejecutando una aplicación Spring Boot que usa TestNG como marco de prueba. Mis pruebas están configuradas así:
Una clase principal, que está a cargo de la lógica de configuración y se encarga de todos los aspectos de configuración:
@ContextConfiguration(classes = {TestingConfig.class}, initializers = ConfigFileApplicationContextInitializer.class) @ContextConfiguration(classes = TestConfig.class) @TestPropertySource(locations = "classpath:application.yml") public abstract ParentTestClass extends AbstractTestNGSpringContextTests { @Autowired private ServiceClient serviceClient; @BeforeSuite public void beforeClass() { Assert.assertNotNull(serviceClient); serviceClient.doSomeSetupWork(); } }Hay varias clases de prueba para niños. Cada uno hereda de la clase de prueba principal para que compartan la misma lógica de configuración.
public ChildTestClass1 extends ParentTestClass { @Test public void someTest() { ... } // More tests not shown } public ChildTestClass2 extends ParentTestClass { @Test public void anotherTest() { ... } // More tests not shown } serviceClient es un cliente para uno de los servicios web de los que depende el conjunto de pruebas. Estoy haciendo llamadas con el cliente del servicio para configurar los datos en el otro servicio antes de ejecutar los casos de prueba.
El problema es este: anteriormente estaba usando la anotación @BeforeClass , lo que significaba que el método de configuración de la clase principal se ejecutaba una vez para cada clase de prueba secundaria. Esto estuvo bien, pero fue muy lento esperar a que la misma configuración se ejecutara varias veces.
Así que pensé para mis adentros: ¡simplemente cambiaré las anotaciones @BeforeClass en ParentTestClass para que sean @BeforeSuite en su lugar! ¡Eso resolverá todos mis problemas!
Equivocado.
Ahora, cuando lo ejecuto, Assert.assertNotNull(serviceClient); falla la línea en el método beforeClass() de la clase padre. En resumen, las dependencias de Spring no se inyectan en el método anotado @BeforeSuite, aunque se inyectaron en el método cuando se anotó con @BeforeClass .
¿Alguna idea aquí? ¡Realmente lo apreciaría!
Creo que esto está funcionando según lo diseñado. Al observar cómo se construye la implementación dentro de org.springframework.test.context.testng.AbstractTestNGSpringContextTests (desde el cual se extiende), las dependencias se inyectan en su clase de prueba a través de org.springframework.test.context.support.DependencyInjectionTestExecutionListener#injectDependencies (este es un oyente). Todos los oyentes, incluido DependencyInjectionTestExecutionListener , se invocan solo a través org.springframework.test.context.testng.AbstractTestNGSpringContextTests#springTestContextPrepareTestInstance que es un método clasificado @BeforeClass(alwaysRun=true) .
Por lo tanto, sus dependencias no estarán disponibles hasta que este método anotado @BeforeClass se ejecute hasta su finalización. Por lo tanto, tendría que sacar su método @BeforeSuite y hacer que funcione solo con una anotación @BeforeClass .
Si no necesita que la configuración de su servicio se realice varias veces, entonces deberá agregar una verificación de edición en su código de prueba que realice la configuración SOLO SI NO SE HA HECHO .
Aquí está la solución a todos sus problemas.
@Override @BeforeSuite protected void springTestContextPrepareTestInstance() throws Exception { super.springTestContextPrepareTestInstance(); }Espero que esto te ayude a inyectar las dependencias.