2017-03-15 45 views
2

我正在做一些Java測試中的DAO測試,並且我定義了一個類來設置與測試數據庫的連接,如JUnit測試-HW我可以設置我的數據庫連接,以避免由於達到最大數據庫連接而導致測試失敗

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

applicationTest.yml文件包含標準的數據庫連接,就像

 # 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 

我現在有二十多個是在每個平均5測試用例,連接到數據庫測試用例類。正如你所看到的,我在我的實驗中使用了dropwizard和hibernate;我的DAO類使用Hibernate C-R-U-D(crate,read,updte,delete)方法,並且連接到postgres數據庫。並且每個類extends這個DAOTestConfig類。 我跑在我的本地michine測試,但我想用一個遠程數據庫實例,而現在我的一些測試與錯誤Error calling Driver#connect

這裏失敗是一個測試中的堆棧跟蹤的一個例子失敗:

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 

在我的本地機器,我在這添加周圍的工作,使我通過了所有測試,通過改變從100到300的最大連接數,但現在,我想找到的情況下,一個永久性的解決方案這個數字在未來會變小。還有其他項目將使用同一個遠程數據庫實例。

我已經搜索瞭解決方案,但我找不到它。要麼沒有,要麼我問的是錯誤的問題。誰可以幫我這個事?

謝謝。

+0

我會推薦使用虛擬機來測試遠程連接。爲了實現這個過程的自動化,你可能需要看一下'vagrant'和'ansible'。流浪者主持你的虛擬主機,並且用任何你想要的方式設置它。快速指南:https://yobriefca.se/blog/2015/05/20/provisioning-postgres-via-vagrant-and-ansible/ |如果您在生產環境中需要特定設置,則應將其定義爲需求並通知相應的人員進行必要的更改。另外:完成後不應該關閉'sessionFactory'嗎? – showp1984

+1

你使用連接池嗎?一般來說,保持連接池很小並且JDBC連接併發性高是一個好習慣。即使100個連接也有點過分。 –

+0

@DmitrySavinkov我不使用連接拉。我在我的問題中發佈的類是我所做的全部連接到數據庫的。 – mupierrix

回答

2

Hw的可以設置我的連接數據庫,以避免由於測試最大DB連接失敗達到

當單元測試你不連接到數據庫。

模擬執行實際數據庫連接並將它們配置爲返回適合您的測試用例的定義良好的值的類。爲了做到這一點,你可以使用模擬框架,如Mockito或類似的。

另請參閱您自己的代碼的單元測試驗證行爲。您的測試驗證連接到數據庫的代碼的行爲,這看起來像您使用的一些框架。如果你不相信這個框架,這隻會被需要,但如果它不值得信任,那你爲什麼要使用它呢?

+0

是的,當我測試爲我的UI獲取數據的HTTP請求時,確實使用mockito框架來模擬服務中的DAO。從我開始測試java代碼或使用java語言進行編程已經很久了。我查看的大部分代碼都是連接到數據庫的。但我會進一步研究這一點。還有一點是,有些DAO會返回一個包含大量數據的對象,尤其是如果我的POJO擁有'@ OneToMany'或'@ ManyToMany'註釋時,這會很痛苦,就像在文件中一樣,並且從那裏。但我想這比連接數據庫容易。 – mupierrix

相關問題