unitarias tutorial test software pruebas generar framework espaƱol java spring junit spring-annotations

java - tutorial - Poblando Spring @Value durante la prueba unitaria



test junit netbeans (5)

Intento escribir una prueba unitaria para un bean simple que se usa en mi programa para validar formularios. El bean está anotado con @Component y tiene una variable de clase que se inicializa usando @Value("${this.property.value}") private String thisProperty;

Me gustaría escribir pruebas unitarias para los métodos de validación dentro de esta clase; sin embargo, si es posible, me gustaría hacerlo sin utilizar el archivo de propiedades. Mi razonamiento detrás de esto, es que si el valor que estoy extrayendo del archivo de propiedades cambia, me gustaría que eso no afecte mi caso de prueba. Mi caso de prueba es probar el código que valida el valor, no el valor en sí mismo.

¿Hay alguna forma de usar código Java dentro de mi clase de prueba para inicializar una clase Java y rellenar la propiedad Spring @Value dentro de esa clase y luego usar eso para probar?

Encontré este cómo que parece estar cerca, pero todavía usa un archivo de propiedades. Prefiero que todo sea código Java.

Gracias


Agregar PropertyPlaceholderConfigurer en la configuración me funciona.

@Configuration @ComponentScan @EnableJpaRepositories @EnableTransactionManagement public class TestConfiguration { @Bean public DataSource dataSource() { EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); builder.setType(EmbeddedDatabaseType.DERBY); return builder.build(); } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); entityManagerFactoryBean.setDataSource(dataSource()); entityManagerFactoryBean.setPackagesToScan(new String[] { "com.test.model" }); // Use hibernate JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter); entityManagerFactoryBean.setJpaProperties(getHibernateProperties()); return entityManagerFactoryBean; } private Properties getHibernateProperties() { Properties properties = new Properties(); properties.put("hibernate.show_sql", "false"); properties.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect"); properties.put("hibernate.hbm2ddl.auto", "update"); return properties; } @Bean public JpaTransactionManager transactionManager() { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(entityManagerFactory().getObject()); return transactionManager; } @Bean PropertyPlaceholderConfigurer propConfig() { PropertyPlaceholderConfigurer placeholderConfigurer = new PropertyPlaceholderConfigurer(); placeholderConfigurer.setLocation(new ClassPathResource("application_test.properties")); return placeholderConfigurer; }

}

Y en clase de prueba

@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = TestConfiguration.class) public class DataServiceTest { @Autowired private DataService dataService; @Autowired private DataRepository dataRepository; @Value("${Api.url}") private String baseUrl; @Test public void testUpdateData() { List<Data> datas = (List<Data>) dataRepository.findAll(); assertTrue(datas.isEmpty()); dataService.updateDatas(); datas = (List<Data>) dataRepository.findAll(); assertFalse(datas.isEmpty()); }

}


Desde Spring 4.1, puede configurar los valores de las propiedades solo en código utilizando la anotación org.springframework.test.context.TestPropertySource en el nivel de clase Pruebas unitarias. Puede usar este enfoque incluso para inyectar propiedades en instancias de beans dependientes

Por ejemplo

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = FooTest.Config.class) @TestPropertySource(properties = { "some.bar.value=testValue", }) public class FooTest { @Value("${some.bar.value}") String bar; @Test public void testValueSetup() { assertEquals("testValue", bar); } @Configuration static class Config { @Bean public static PropertySourcesPlaceholderConfigurer propertiesResolver() { return new PropertySourcesPlaceholderConfigurer(); } } }

Nota: es necesario tener una instancia de org.springframework.context.support.PropertySourcesPlaceholderConfigurer en el contexto Spring

Editar 24-08-2017: Si usa SpringBoot 1.4.0 y posterior, puede inicializar las pruebas con las anotaciones @SpringBootTest y @SpringBootConfiguration . Más información here

En caso de SpringBoot tenemos el siguiente código

@SpringBootTest @SpringBootConfiguration @RunWith(SpringJUnit4ClassRunner.class) @TestPropertySource(properties = { "some.bar.value=testValue", }) public class FooTest { @Value("${some.bar.value}") String bar; @Test public void testValueSetup() { assertEquals("testValue", bar); } }


Esto parece funcionar, aunque sigue siendo un poco detallado (me gustaría algo más corto aún):

@BeforeClass public static void beforeClass() { System.setProperty("some.property", "<value>"); } // Optionally: @AfterClass public static void afterClass() { System.clearProperty("some.property"); }



Si lo desea, puede ejecutar las pruebas en Spring Context y establecer las propiedades requeridas dentro de la clase de configuración de Spring. Si usa JUnit, use SpringJUnit4ClassRunner y defina la clase de configuración dedicada para sus pruebas de esa manera:

La clase bajo prueba:

@Component public SomeClass { @Autowired private SomeDependency someDependency; @Value("${someProperty}") private String someProperty; }

La clase de prueba:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SomeClassTestsConfig.class) public class SomeClassTests { @Autowired private SomeClass someClass; @Autowired private SomeDependency someDependency; @Before public void setup() { Mockito.reset(someDependency); @Test public void someTest() { ... } }

Y la clase de configuración para esta prueba:

@Configuration public class SomeClassTestsConfig { @Bean public static PropertySourcesPlaceholderConfigurer properties() throws Exception { final PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer(); Properties properties = new Properties(); properties.setProperty("someProperty", "testValue"); pspc.setProperties(properties); return pspc; } @Bean public SomeClass getSomeClass() { return new SomeClass(); } @Bean public SomeDependency getSomeDependency() { // Mockito used here for mocking dependency return Mockito.mock(SomeDependency.class); } }

Habiendo dicho eso, no recomendaría este enfoque, solo lo agregué aquí para referencia. En mi opinión, una forma mucho mejor es usar Mockito runner. En ese caso, no ejecuta pruebas dentro de Spring en absoluto, lo cual es mucho más claro y simple.