java 您将如何测试连接池

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5134515/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 09:38:02  来源:igfitidea点击:

How would you test a Connection Pool

javaunit-testingtestingintegration-testingconnection-pooling

提问by nbarraille

I have implemented a very simple ConnectionPool in Java. It has no fancy features, just get/release connection methods.

我已经用 Java 实现了一个非常简单的 ConnectionPool。它没有花哨的功能,只是获取/释放连接方法。

How can I test it is working?

我如何测试它是否有效?

I know there are plenty of connection Pools ready to use out there, which are much more reliable than what I'll do, but I am just trying to practice to understand how connections Pool work.

我知道有很多连接池可供使用,它们比我要做的要可靠得多,但我只是想练习了解连接池的工作原理。

Thank you!

谢谢!

Here is the code in case it helps:

这是代码,以防万一:

public class ConnectionPoolImpl implements ConnectionPool {
    private Vector<PooledConnection> connections; // The connections container
    String url;
    String username; 
    String password;

    /**
     * Instanciates a new MySQLConnectionPool
     * @param nbConnectionsMax
     */
    public ConnectionPoolImpl(String DBUrl, String username, String password){
        this.connections = new Vector<PooledConnection>();
        this.url = DBUrl;
        this.username = username;
        this.password = password;
    }

    /**
     * Returns a connection from the pool, if some are available, or create a new one.
     * 
     * @return the connection.
     */
    public Connection getConnection() throws SQLException {
        synchronized(this.connections){
            // Checking if there is an available connection to return
            for(PooledConnection c : this.connections){
                if(!c.isUsed()){
                    c.setUsed();
                    return c.getConnection();
                }
            }

            // If there are none, open a new one and return it
            Connection conn = DriverManager.getConnection(url, username, password);
        PooledConnection pConn = new PooledConnection(conn);
        pConn.setUsed();
        connections.add(pConn);
        return pConn.getConnection();
        }
    }

    /**
     * Releases a connection to the pool.
     * 
     * @param con the connection to release.
     */
    public void releaseConnection(Connection con) throws SQLException {
        synchronized(this.connections){
            for(PooledConnection c : this.connections){
                if(c.getConnection().equals(con)){
                    c.setFree();
                    return;
                }
            }
        }
      }
}

And my PooledConnection.java:

还有我的 PooledConnection.java:

public class PooledConnection {
    private Connection conn;
    private boolean used;

    public PooledConnection(Connection conn){
        this.conn = conn;
        this.used = false;
    }

    public void setUsed(){
        this.used = true;
    }

    public void setFree(){
        this.used = false;
    }

    public boolean isUsed(){
        return this.used;
    }

    public Connection getConnection(){
        return this.conn;
    }
}

回答by JB Nizet

You could test that

你可以测试一下

  • getting a connection when the pool is empty gives you a connection
  • getting a connection when a connection has already been got and not released gives you another, different connection
  • releasing a connection doesn't throw any exception
  • getting a connection after one has been released gives you the same connection
  • 当池为空时获得连接会给你一个连接
  • 当一个连接已经被获取并且没有被释放时获取一个连接会给你另一个不同的连接
  • 释放连接不会抛出任何异常
  • 释放后获得连接会为您提供相同的连接

Note that such a unit test would need a real database, with a real user and password to test. You could make your connection pool depend on a DataSource, and build your ConnectionPool using a mock DataSource returning mock Connections, in order to be able to test the class without depending on a real database.

请注意,这样的单元测试需要一个真实的数据库,有真实的用户和密码来测试。您可以使连接池依赖于数据源,并使用返回模拟连接的模拟数据源构建连接池,以便能够在不依赖真实数据库的情况下测试该类。

回答by Michael Easter

For an integration test, you could use dbUnitto load the database with prepared data and then write tests that query the database.

对于集成测试,您可以使用dbUnit将准备好的数据加载到数据库,然后编写查询数据库的测试。

For an unit test, you might consider using a mocking library such as Mockitoto ensure that you get the behaviour you expect. No database necessary in this case. [EDIT: However, due to the static method calls like DriverManager.getConnection(), this will require some refactoring and/or dependency injection.]

对于单元测试,您可能会考虑使用Mockito 之类的模拟库来确保获得预期的行为。在这种情况下不需要数据库。[编辑:但是,由于像 DriverManager.getConnection() 这样的静态方法调用,这将需要一些重构和/或依赖注入。]

By combining both the unit tests and integration tests (and mix in some multi-threaded unit tests), you can go a long way towards testing your work.

通过结合单元测试和集成测试(并混合一些多线程单元测试),您可以在很大程度上测试您的工作。

回答by duffymo

Industrial strength connection pools have the ability to check connections by making a connection and executing a simple SQL query (e.g. "SELECT 1") to ensure that connection is viable before giving it out. Yours does not.

工业强度的连接池能够通过建立连接并执行简单的 SQL 查询(例如“SELECT 1”)来检查连接,以确保在发出连接之前连接是可行的。你的没有。

I don't see where you can initialize the connection pool with a fixed number of connections. The whole point of a connection pool is to amortize the cost of creating a connection over all clients.

我看不到在哪里可以使用固定数量的连接初始化连接池。连接池的全部意义在于分摊在所有客户端上创建连接的成本。

I'd worry about the design of your connection pool.

我会担心您的连接池的设计。

As for testing, just start writing unit tests. Since your pool will be shared, be sure to write some multi-threaded tests to make sure that it's really thread safe.

至于测试,就开始编写单元测试吧。由于您的池将被共享,请务必编写一些多线程测试以确保它确实是线程安全的。

回答by MRalwasser

You should also test concurrency/scalability under load using multiple threads.

您还应该使用多线程测试负载下的并发性/可扩展性。