Question

Dans mes tests unitaires, j'autowired quelques sources de données, qui utilisent des URL comme

jdbc:derby:memory:mydb;create=true

pour créer un DB en mémoire.

Pour supprimer un Derby db en mémoire que vous devez vous connecter avec:

jdbc:derby:memory:mydb;drop=true

Je voudrais que cela se produise après chaque test et commencer par un db frais. Comment puis-je faire cela en utilisant Spring?

Était-ce utile?

La solution 2

Comment arrêter Derby base de données en mémoire correctement

m'a donné un indice à une solution:

    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 inconvénient est l'utilisation de la chaîne constructeur qui accepte une chaîne (un objet immuable de chaîne autour d'un objet immuable de chaîne). Je lis qu'il ya une annotation @Value au printemps 3, ce qui pourrait aider, mais j'utilise Spring 2.5.

S'il vous plaît laissez-moi savoir si vous avez une solution plus agréable.

Autres conseils

Il y a une façon de faire cette base de données agnostique si vous utilisez Spring avec Hibernate.

Assurez-vous que le contexte d'application sera créé / détruite avant / après chaque méthode d'essai:

@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 {

}

Instruire Hibernate créer automatiquement le schéma au démarrage et d'abandonner le schéma à l'arrêt:

hibernate.hbm2ddl.auto = create-drop

avant chaque test

  • le contexte d'application est créée et les grains de ressort requis sont injectés (ressort)
  • les structures de base de données sont créés (mise en veille prolongée)
  • la import.sql est exécutée si elle est présente (mise en veille prolongée)

et après tous les tests

  • le contexte d'application est détruite (ressort)
  • le schéma de base de données est supprimée (veille prolongée).

Si vous utilisez les transactions, vous pouvez ajouter le TransactionalTestExecutionListener.

Après le test du ressort 3, vous pouvez utiliser des annotations pour injecter des configurations:

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

Il suffit de faire quelque chose comme:

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;
    }
}

Faites votre haricots ont une portée de prototype (scope="prototype"). Cela aura une nouvelle instance de la source de données avant chaque test.

Si vous utilisez la bibliothèque printemps-test.jar , vous pouvez faire quelque chose comme ceci:

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);
    }
}

Et une version mise à jour basée sur le dernier commentaire, qui laisse tomber les tables db et reconstitue avant chaque test:

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);
        }
}

est ce que nous faisons au début de chaque test.

  1. Rejeter tous les Objects précédents.

  2. Créer toutes les tables mentionnées dans le create_table.sql

  3. Les valeurs insert sur les tables créées à partir de ce que vous voulez tester.

      @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");
    
      }
    

fonctionne comme un charme!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top