【问题标题】: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 帐户凭据用于身份验证(请参阅 MSDN 和 here 的详细信息)。对于 SQL Server,建议使用此选项(值 True 或 SSPI)。

同时,此选项对 LocalDB 服务器没有任何影响。无论此设置如何,LocalDB 仍将是一个用户实例,在启动它的帐户下运行。基本上,它就像Integrated Security 设置为True 或SSPI。 LocalDB 中没有办法阻止用户访问其数据库中的数据(例如,通过使用 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
    相关资源
    最近更新 更多