2011-01-17 11 views
6

En mis pruebas de unidad que autowired algunos DataSources, que utilizan direcciones URL comoJUnit + + Derby de primavera: caída db en memoria después de cada prueba

jdbc:derby:memory:mydb;create=true 

para crear un DB en memoria.

Para soltar un Derby en memoria db tiene que conectar con:

jdbc:derby:memory:mydb;drop=true 

me gustaría que esto suceda después de cada prueba y comenzar con una base de datos nueva. ¿Cómo puedo hacer esto usando Spring?

Respuesta

4

How to shutdown Derby in-memory database Properly

me dio una pista a una solución:

mydb.drop.url = jdbc:derby:memory:mydb;drop=true 

    ... 

    <bean id="mydbDropUrl" class="java.lang.String"> 
    <constructor-arg value="${mydb.drop.url}" /> 
</bean> 

    ... 

    @Resource 
private String mydbDropUrl;   

    @After 
public void tearDown() { 
    try { 
     DriverManager.getConnection(mydbDropUrl); 
    } catch (SQLException e) { 
     // ignore 
    } 
} 

Un inconveniente es el uso del constructor de cadena que acepta un String (una Cadena de objeto inmutable alrededor de un objeto Cadena inmutable). Leí que hay una anotación @Value en Spring 3, lo que podría ayudar aquí, pero estoy usando Spring 2.5.

Háganme saber si usted tiene una solución más agradable.

+0

Siguiendo http://docs.oracle.com/javadb/10.8.1.2/getstart/rwwdactivity3.html como ejemplo, en lugar de simplemente capturar y descartar la 'SQLException', sería mejor descartarla solo si' e.getSQLState() .equals ("08006") ' – Raedwald

1

Si utiliza el primavera-test.jar biblioteca, puede hacer algo como esto:

public class MyDataSourceSpringTest extends 
AbstractTransactionalDataSourceSpringContextTests { 

    @Override 
    protected String[] getConfigLocations() { 
     return new String[]{"classpath:test-context.xml"}; 
    } 

    @Override 
    protected void onSetUpInTransaction() throws Exception { 
     super.deleteFromTables(new String[]{"myTable"}); 
     super.executeSqlScript("file:db/load_data.sql", true); 
    } 
} 

y una versión actualizada en base al último comentario, que cae y vuelve a crear tablas db antes de cada prueba:

public class MyDataSourceSpringTest extends 
    AbstractTransactionalDataSourceSpringContextTests { 

     @Override 
     protected String[] getConfigLocations() { 
      return new String[]{"classpath:test-context.xml"}; 
     } 

     @Override 
     protected void onSetUpInTransaction() throws Exception { 
      super.executeSqlScript("file:db/recreate_tables.sql", true); 
     } 
} 
+0

yup, know your libs (+1) –

+0

No quiero eliminar datos de tablas o incluso eliminar tablas. Quiero dejar todo el archivo db y recrearlo para cada prueba, que es más seguro en mi humilde opinión. – Puce

+0

Puede crear un script sql que suelte el archivo db y vuelva a crear las tablas y ejecútelo como se muestra arriba. Actualizaré mi respuesta de manera apropiada. –

1

Eso sí, algo así como:

public class DatabaseTest implements ApplicationContextAware { 
    private ApplicationContext context; 
    private DataSource source; 

    public void setApplicationContext(ApplicationContext applicationContext) { 
     this.context = applicationContext; 
    } 

    @Before 
    public void before() { 
     source = (DataSource) dataSource.getBean("dataSource", DataSource.class); 
    } 

    @After 
    public void after() { 
     source = null; 
    } 
} 

Haga que su grano tenga un alcance de prototipo (scope="prototype"). Esto obtendrá una nueva instancia de la fuente de datos antes de cada prueba.

+0

Eso es inteligente (+1), pero no es muy práctico (significa que tiene que conectar manualmente todos los beans que usan el origen de datos) –

+0

Tengo dudas, si este enfoque realmente funciona: ¿Está diciendo que context.getBean() volverá una nueva instancia en lugar de la misma instancia? No creo que este sea el caso, lo que significa que no ganarás nada. Hay una anotación @DirtiesContext, pero incluso eso no abriría una conexión con "jdbc: derby: memory: mydb; drop = true" para eliminar el db en memoria. – Puce

2

Después de 3 pruebas de la primavera, puede utilizar las anotaciones para inyectar configuraciones:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration("/spring-test.xml") 
public class MyTest { 
} 
5

No es una forma de base de datos independiente del de hacer esto si está utilizando la primavera junto con Hibernate.

Asegúrese de que el contexto de aplicación se creará/destruidos antes/después de cada método de prueba:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({"classpath*:application-context-test.xml"}) 
@TestExecutionListeners({DirtiesContextTestExecutionListener.class, 
    DependencyInjectionTestExecutionListener.class}) 
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) 
public abstract class AbstractTest { 

} 

Instruya Hibernate para crear automáticamente el esquema en el arranque y para descartar el esquema en el apagado:

hibernate.hbm2ddl.auto = create-drop 

Ahora antes de cada prueba

  • se crea el contexto de aplicación y requieren la d primavera se inyectan los frijoles (primavera)
  • las estructuras de la base de datos se crean (hibernación)
  • la importación.se ejecuta sql si está presente (hibernación)

y después de cada prueba

  • se destruye el contexto de aplicación (resorte)
  • se deja caer el esquema de base de datos (hibernación).

Si está utilizando transacciones, es posible que desee agregar el TransactionalTestExecutionListener.

0

Esto es lo que hacemos al inicio de cada prueba.

  1. Suelta todos los objetos anteriores.

  2. crear todas las tablas mencionadas en el create_table.sql

  3. Inserte valores en las tablas creadas en base a lo que desea probar.

    @Before 
        public void initialInMemoryDatabase() throws IOException, FileNotFoundException { 
    
        inMemoryDerbyDatabase.dropAllObjects(); 
        inMemoryDerbyDatabase.executeSqlFile("/create_table_policy_version_manager.sql"); 
        inMemoryDerbyDatabase.executeSqlFile("/insert_table_policy_version_manager.sql"); 
    
        } 
    

funciona como un encanto!

Cuestiones relacionadas