H2 PostgreSQL mode ne semble pas fonctionner pour moi

Bonjour mon application accède à la base de données Postgres et j'ai de nombreuses requêtes prédéfinies (Rank,Parition,complex join etc) je tire contre Postgres. Maintenant, je veux aller à l'unité tester ces requêtes comportement avec de petites données de test. J'ai commencé avec H2/Junit. J'ai découvert que la plupart des requêtes Postgres comme Rank, Partition, Complex case when update etc. J'ai donc pensé à utiliser le mode de compatibilité H2 PosgreSQL en pensant que toutes les requêtes postgres fonctionneront sur H2. corrigez-moi si je me trompe.

j'ai suivi la documentation H2 disant d'utiliser le mode PostgreSQL, utiliser L'URL de la base de données jdbc:h2:~/test;MODE=PostgreSQL ou la déclaration SQL SET MODE PostgreSQL.

j'ai activé le mode en utilisant SET MODE PostgreSQL et j'ai essayé de lancer une des requêtes qui implique rank() et fonctionne dans postgres mais elle n'a pas fonctionné H2. Il me donne l'exception suivante

Function "RANK' not found; in SQL statement

s'il vous Plaît guide, je suis nouveau sur H2 et de la base de données de test. Merci à l'avance. J'utilise le pilote H2 jdbc pour lancer des requêtes postgres en pensant que le mode de compatibilité H2 Posgress me permettra de lancer des requêtes postgres.

14
demandé sur u449355 2014-06-14 23:41:35

1 réponses

donc j'ai pensé à utiliser le mode de compatibilité H2 PosgreSQL en pensant que toutes les requêtes postgres fonctionneront sur H2 s'il vous plaît corrigez-moi si je me trompe

ce n'est pas vrai.

H2 essaie d'émuler la syntaxe PostgreSQL et supporte quelques fonctionnalités et extensions. Il ne sera jamais un match complet pour le comportement de PostgreSQL, et ne supporte pas toutes les fonctionnalités.

les seules options que vous avez sont:

  • utiliser PostgreSQL dans les essais; ou
  • arrêter d'utiliser des caractéristiques non supportées par H2

je suggère D'utiliser Pg pour les tests. Il est relativement simple d'écrire un harnais de test que initdb une postgres exemple et lance pour tester ensuite l'arrache après.

mise à jour basée sur les commentaires:

il n'y a pas de ligne dure entre les tests "unité" et "intégration". Dans ce cas, H2 est un composant externe. Les essais de l'unité puriste auraient un répondant fictif aux requêtes dans le cadre du harnais d'essai. Tester avec H2 est tout autant un test" d'intégration " qu'un test avec PostgreSQL. Le fait qu'il est en cours de fabrication et en mémoire est pratique, mais pas fonctionnellement importante.

si vous voulez test unitaire vous devez écrire une autre cible de base de données pour votre application pour aller à côté de votre "PostgreSQL", "SybaseIQ", etc cible. Appelez-le, dites "MockDatabase". Cela devrait juste retourner les résultats attendus des requêtes. Il n'a pas vraiment d'exécuter les requêtes, il n'existe que pour tester le comportement du reste du code.

personnellement, je pense que c'est une énorme perte de temps, mais c'est ce que ferait un puriste de test unitaire pour éviter d'introduire des dépendances externes dans le harnais de test.

si vous insistez pour avoir des tests unitaires (par opposition à l'intégration) pour vos composants DB mais ne peut pas / ne veut pas écrire une interface simulée, vous devez plutôt trouver un moyen d'utiliser une interface existante. H2 serait un candidat raisonnable pour cela - mais vous devrez écrire un nouveau backend avec un nouvel ensemble de requêtes qui fonctionnent pour H2, vous ne pouvez pas simplement réutiliser votre backend PostgreSQL. Comme nous l'avons déjà établi, H2 ne supporte pas toutes les fonctionnalités que vous devez utiliser avec PostgreSQL, vous devrez donc trouver différentes façons de faire les mêmes choses avec H2. Une option serait de créer une base de données H2 simple avec les résultats "attendus" et les requêtes simples qui renvoient ces résultats, ignorant complètement le schéma de l'application réelle. Le seul vrai inconvénient ici est que cela peut être une douleur majeure à maintenir ... mais c'est des tests unitaires.

personnellement, je voulais juste tester avec PostgreSQL. À moins que je ne teste des classes ou des modules individuels qui sont seuls comme des unités étroitement interfacées et bien définies, Je ne me soucie pas si quelqu'un appelle cela un test "d'unité" ou "d'intégration". Je vais test de l'unité, de dire, de données classes de validation. Pour le code d'interface de la base de données, le test de l'unité puriste a très peu de sens et je vais juste faire des tests d'intégration.

bien qu'avoir une base de données en mémoire en cours soit pratique pour cela, il n'est pas nécessaire. Vous pouvez écrire votre harnais de test de sorte que le code de configuration initdb est un nouveau PostgreSQL et le lance; puis le code démonté tue le maître de poste et supprime le datadir. J'ai écrit plus à ce sujet dans cette réponse .

voir aussi:

comme pour:

si toutes les requêtes avec les ensembles de données finales attendus fonctionne bien dans Postgress je peux supposer qu'il fonctionnera bien dans tous les autres dbs

si je comprends ce que vous dites correctement alors oui, c'est le cas - si le reste de votre code fonctionne avec un ensemble de données de PostgreSQL, il devrait généralement fonctionner de la même façon avec un ensemble de données contenant les mêmes données d'une autre base de données. Tant qu'il utilise des types de données simples, pas des fonctionnalités spécifiques à la base de données, bien sûr.

29
répondu Craig Ringer 2017-05-23 10:31:35