2017-03-15 2 views
2

Ich mache einige DAO-Tests in Java, und ich habe eine Klasse definiert, die die Verbindung zur Test-DB wie dieseJUnit testen - Hw kann ich meine DB connect einrichten, um zu vermeiden Tests aufgrund der maximalen DB-Verbindung erreicht

setzt
import io.dropwizard.testing.ResourceHelpers; 
import io.dropwizard.testing.junit.DropwizardAppRule; 
import my.project.package.ProjectTestAppConfiguration; 
import my.project.package.ProjectTestApplication; 
import my.project.package.domain.ProjectClass1; 
import org.hibernate.Session; 
import org.hibernate.SessionException; 
import org.hibernate.SessionFactory; 
import org.hibernate.cfg.Configuration; 
import org.junit.ClassRule; 

import java.util.Map; 
import java.util.logging.Level; 

public class DAOTestConfig { 
    protected SessionFactory sessionFactory; 

    @ClassRule 
    public static final DropwizardAppRule<ProjectTestAppConfiguration> RULE = 
    new DropwizardAppRule<ProjectTestAppConfiguration> 
    (ProjectTestApplication.class, ResourceHelpers.resourceFilePath("applicationTest.yml")); 

    public DAOTestConfig() { 
     Map<String, String> properties = RULE.getConfiguration().getDataSourceFactory().getProperties(); 
     Configuration configuration = new Configuration(); 
     for (Map.Entry<String, String> property : properties.entrySet()) { 
      configuration.setProperty(property.getKey(), property.getValue()); 
     } 

     /* Add annotated classes here */ 

     configuration.addAnnotatedClass(ProjectClass1.class); 

     /* ... */ 

     sessionFactory = configuration.buildSessionFactory(); 
    } 

    public Session getSession() { 
     Session session; 
     try{ 
      session = sessionFactory.getCurrentSession(); 
     } catch (SessionException e) { 
      session = sessionFactory.openSession(); 
     } 
     return session; 
    } 
} 

Meine applicationTest.yml Datei enthält Standard-DB-Verbindung, wie

 # Database settings. 
     database: 

      # the name of your JDBC driver 
      driverClass: org.postgresql.Driver 

      # the username for DB 
      user: ${FH_DB_USER} 

      # the password 
      password: ${FH_DB_PASSWORD} 

      # the JDBC URL 
      url: jdbc:postgresql://${FH_DB_HOST}:${FH_DB_PORT}/${FH_DB_NAME} 

      # any properties specific to your JDBC driver: 
      properties: 
      charSet: UTF-8 
      hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect 
      hibernate.connection.driver_class: org.postgresql.Driver 
      hibernate.temp.use_jdbc_metadata_defaults: false 
      hibernate.connection.url: jdbc:postgresql://${FH_DB_HOST}:${FH_DB_PORT}/${FH_DB_NAME} 
      hibernate.connection.username: ${FH_DB_USER} 
      hibernate.connection.password: ${FH_DB_PASSWORD} 
      hibernate.current_session_context_class: thread 
      hibernate.show_sql: true 

ich derzeit mehr als zwanzig Testfall-Klassen, die einen Durchschnitt von 5 Testfällen in jeweils, die den DB verbindet. Wie Sie sehen können, verwende ich Dropwizard und überwintern in meinen Proekten; Meine DAO-Klassen verwenden Hibernate C-R-U-D-Methoden (crate, read, updte, delete), und die Verbindungen werden mit einer postgres-Datenbank hergestellt. Und jede Klasse extends dieser DAOTestConfig Klasse. Ich war auf meinem lokalen michine den Test läuft, aber ich möchte einen Remote-DB-Instanz verwenden, und jetzt mit dem Fehler einige meiner Tests Error calling Driver#connect

Hier versagen ist ein Beispiel für die Stack-Trace von einem der Tests, die fehlgeschlagen:

org.hibernate.exception.GenericJDBCException: Error calling Driver#connect 
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) 
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) 
    at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.convertSqlException(BasicConnectionCreator.java:118) 
    at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:41) 
    at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.createConnection(BasicConnectionCreator.java:58) 
    at org.hibernate.engine.jdbc.connections.internal.PooledConnections.addConnections(PooledConnections.java:106) 
    at org.hibernate.engine.jdbc.connections.internal.PooledConnections.<init>(PooledConnections.java:40) 
    at org.hibernate.engine.jdbc.connections.internal.PooledConnections.<init>(PooledConnections.java:19) 
    at org.hibernate.engine.jdbc.connections.internal.PooledConnections$Builder.build(PooledConnections.java:138) 
    at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildPool(DriverManagerConnectionProviderImpl.java:110) 
    at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:74) 
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94) 
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:217) 
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189) 
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildBootstrapJdbcConnectionAccess(JdbcEnvironmentInitiator.java:158) 
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.getBootstrapJdbcConnectionAccess(JdbcServicesImpl.java:71) 
    at org.jadira.usertype.spi.shared.AbstractUserTypeHibernateIntegrator.use42Api(AbstractUserTypeHibernateIntegrator.java:83) 
    at org.jadira.usertype.spi.shared.AbstractUserTypeHibernateIntegrator.integrate(AbstractUserTypeHibernateIntegrator.java:206) 
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:276) 
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465) 
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:708) 
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724) 
    at my.project.package.persistence.DAOTestConfig.<init>(DAOTestConfig.java:106) 
    at my.project.package.persistence.ProjectClass1DAOTest.<init>(ProjectClass1DAOTest.java:19) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
    at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217) 
    at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48) 
    at org.junit.rules.RunRules.evaluate(RunRules.java:20) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189) 
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165) 
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85) 
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115) 
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75) 
Caused by: org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections 
    at org.postgresql.core.v3.ConnectionFactoryImpl.readStartupMessages(ConnectionFactoryImpl.java:691) 
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:207) 
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) 
    at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:149) 
    at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:35) 
    at org.postgresql.jdbc3g.AbstractJdbc3gConnection.<init>(AbstractJdbc3gConnection.java:22) 
    at org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:47) 
    at org.postgresql.jdbc42.AbstractJdbc42Connection.<init>(AbstractJdbc42Connection.java:21) 
    at org.postgresql.jdbc42.Jdbc42Connection.<init>(Jdbc42Connection.java:28) 
    at org.postgresql.Driver.makeConnection(Driver.java:415) 
    at org.postgresql.Driver.connect(Driver.java:282) 
    at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:38) 
    ... 50 more 

auf meinem lokalen Rechner habe ich auf diese eine Arbeit um alle passieren meine Tests zu machen, indem die maximale Verbindungszahl von 100 bis 300 zu ändern, aber jetzt, dass ich eine dauerhafte Lösung für den Fall finden möchten diese Zahl wird in der Zukunft klein. Und es gibt andere Projekte, die dieselbe Remote-DB-Instanz verwenden.

Ich habe nach der Lösung gegoogelt, aber ich kann es nicht finden. Entweder gibt es keine oder ich stelle die falsche Frage. Kann mir jemand dabei helfen?

Vielen Dank.

+0

Ich würde empfehlen, eine virtuelle Maschine zu verwenden, um eine Remote-Verbindung zu testen. Um diesen Prozess zu automatisieren, sollten Sie sich "vagrant" und "ansible" ansehen. Vagrant hosts Ihre vm und ansible richtet es mit was auch immer Sie möchten. Eine Kurzanleitung: https://yobriefca.se/blog/2015/05/20/provisioning-postgres-via-vagrant-and-ansible/ | Wenn Sie in Ihrer Produktionsumgebung bestimmte Einstellungen benötigen, sollten Sie dies als Anforderung definieren und die entsprechenden Mitarbeiter informieren, damit sie die erforderlichen Änderungen vornehmen können. Außerdem: Sollten Sie die 'sessionFactory' nicht schließen, nachdem Sie damit fertig sind? – showp1984

+1

Verwenden Sie einen Verbindungspool? Im Allgemeinen empfiehlt es sich, den Verbindungspool klein und die JCBC-Verbindungskonkurrenzen hoch zu halten. Selbst 100 Verbindungen sind irgendwie übertölpelnd. –

+0

@DmitrySavinkov Ich verwende keine Verbindung ziehen. Die Klasse, die ich in meine Frage geschrieben habe, ist alles, was ich mache, um eine Verbindung zur Datenbank herzustellen. – mupierrix

Antwort

2

Hw kann ich meine DB anschließen Tests zu vermeiden, durch maximale DB-Verbindung versagt erreicht

Wenn Sie Unittesting keine Verbindung zu einer Datenbank.

Sie mock die Klassen, die die tatsächliche Datenbankverbindung durchführen und sie so konfigurieren, dass sie genau definierte Werte zurückgibt, die für Ihren Testfall geeignet sind. Um dies zu tun, können Sie ein spöttisches Framework wie Mockito oder ähnliches verwenden.

Auch UnitTest Verify Verhalten von Ihre eigenen Code. Ihr Test überprüft das Verhalten des Codes, der mit der Datenbank verbunden ist, und dies ähnelt einem von Ihnen verwendeten Framework. Dies wäre nur erforderlich, wenn Sie diesem Framework nicht vertrauen, aber wenn es nicht vertrauenswürdig ist, warum verwenden Sie es dann?

+0

Ja, tatsächlich benutze ich das Mockito-Framework, um die DAOs in den Diensten zu verspotten, wenn ich eine HTTP-Anfrage teste, die Daten für meine UI holt. Es ist nicht mehr lange her, dass ich mit dem Testen von Java-Code oder dem Programmieren mit Java-Sprache begonnen habe. Der meiste Code, den ich mir angeschaut habe, testet, dass DAOs sich mit der DB verbinden. Aber ich werde weiter darüber nachforschen. Ein weiterer Grund ist, dass einige DAOs ein Objekt mit vielen Daten zurückgeben, besonders wenn mein POJO '@ OneToMany' oder' @ ManyToMany' Annotationen hat, das wäre ein Aufwand, wie in einer Datei zu sagen und zu lesen Dort. Aber ich denke, es wird einfach sein als eine Verbindung zur DB. – mupierrix

Verwandte Themen