【问题标题】:Can't open sqlconnection within nunit test无法在 nunit 测试中打开 sqlconnection
【发布时间】:2014-09-14 17:49:17
【问题描述】:

我遇到了一个我无法弄清楚的奇怪问题。我正在尝试围绕一些数据库代码编写一些集成测试,但我的单元测试因一个奇怪的异常而失败。在控制台应用程序下正常运行代码就可以了。

public static class DatabaseManager
{
    public static VerifyServceConnectionResult VerifyServerConnection(Server server)
    {
        try
        {

            using (var conn = new SqlConnection(BuildConnectionString(server)))
            {
                conn.Open();
            }

            return new VerifyServceConnectionResult { ConnectionSuccessful = true };
        }
        catch (SqlException ex)
        {
            return new VerifyServceConnectionResult
            {
                ConnectionSuccessful = false, 
                ErrorMessage = ex.Message
            };
        }
        catch (Exception ex)
        {
            return new VerifyServceConnectionResult
            {
                ConnectionSuccessful = false,
                ErrorMessage = "General Exception: " + ex.Message
            };
        }
    }

    private static string BuildConnectionString(Server server)
    {
        var builder = new SqlConnectionStringBuilder();

        builder.DataSource = server.DataSource;
        builder.IntegratedSecurity = server.UseIntegratedSecurity;

        return builder.ConnectionString;
    }

}

只要在 Nunit 测试中调用 conn.open,我就会得到一个异常“算术运算导致溢出”。关于为什么这样一个简单的测试会在 nunit 中以如此奇怪的错误失败的任何想法。同样,代码在单元测试的上下文之外也能正常工作。

谢谢

编辑:添加堆栈跟踪

at SNIOpenSyncExWrapper(SNI_CLIENT_CONSUMER_INFO* , SNI_ConnWrapper** )
at SNINativeMethodWrapper.SNIOpenSyncEx(ConsumerInfo consumerInfo, String constring, IntPtr& pConn, Byte[] spnBuffer, Byte[] instanceName, Boolean fOverrideCache, Boolean fSync, Int32 timeout, Boolean fParallel)
at System.Data.SqlClient.SNIHandle..ctor(ConsumerInfo myInfo, String serverName, Byte[] spnBuffer, Boolean ignoreSniOpenTimeout, Int32 timeout, Byte[]& instanceName, Boolean flushCache, Boolean fSync, Boolean fParallel)
at System.Data.SqlClient.TdsParserStateObject.CreatePhysicalSNIHandle(String serverName, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Byte[]& instanceName, Byte[] spnBuffer, Boolean flushCache, Boolean async, Boolean fParallel)
at System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean withFailover)
at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover)
at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
at xxx.Database.DatabaseManager.VerifyServerConnection(Server server) in d:\projects\TFS\xxx.visualstudio.com\SnydJK.DatabaseUtility\Database\DatabaseManager.cs:line 17

【问题讨论】:

  • 您是否尝试过设置断点并通过 Visual Studio 调试单元测试?
  • 是的,但是框架中的所有内容都已关闭,完整的堆栈跟踪似乎没有帮助,但我会将其添加到帖子中以防对任何人有所帮助。

标签: c# sql testing nunit


【解决方案1】:

最近,我遇到了相同调用堆栈的异常。

环境

我在 Windows 8.1 64 位(不在域中)使用默认 UAC 设置的 LocalDB 服务器,用户是本地管理员,Framework v4.0.2(请参阅why it's important)。 遗憾的是,该问题无法在具有相同环境的其他计算机上重现。

问题描述

发现异常发生在以下几种情况:

  • 连接字符串中有Integrated Security参数,用于新建数据库。
  • 相同的进程会在新创建的数据库创建后打开一个连接。

打破这两个条件之一可以毫无例外地通过。所以省略Integrated Security 是最简单的方法。作为一个选项 - 不要在同一进程中打开与新创建的数据库的连接。但是,如果我们仍然在一个进程的范围内工作,那么在创建数据库后添加暂停将无济于事。

解决方案

LocalDB打交道时,去掉连接字符串中的Integrated Security参数。

一般评论

Integrated Security 是一个选项,它指定 Windows 帐户凭据用于身份验证(请参阅 MSDNhere 的详细信息)。对于 SQL Server,建议使用此选项(值 TrueSSPI)。

同时,此选项对 LocalDB 服务器没有任何影响。无论此设置如何,LocalDB 仍将是一个用户实例,在启动它的帐户下运行。基本上,它就像Integrated Security 设置为TrueSSPILocalDB 中没有办法阻止用户访问其数据库中的数据(例如,通过使用 SQL 授权)。一旦用户可以访问数据库文件,他们就可以启动自己的 LocalDB 实例并打开数据库。

因此,所有在连接到 LocalDB 时指定 Integrated Security 的建议都没有根据。

【讨论】:

    猜你喜欢
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多