If you are writing you code to be able to easily unit test each method, and you would like to unit test situations where a SqlException exception is thrown, then you’ll definitely run into the issue of the SqlException objects constructor being marked “internal.” Members marked “internal” can be a nightmare for unit testing, and they are found all over the place in the .NET Framework. Basically you can’t call “internal” methods, constructors, fields, etc from you own code because it doesn’t reside within the same assembly as the internal code. Or can you? Actually, Yes, you can, but only with a little help from reflection. While it is not recommended (because of permissions, performance, and such) to do this within your applications, it should be perfectly fine within your Unit Test code base.
While working on my dotNetExt project, I wrote a simple helper that allowed me to easily instantiate a SqlException object with a specified error number. This allows me to write units tests that throw any SqlException I want, when I want.
Here’s a direct link to the source code for the SqlExceptionHelper.Generate method:
http://dotnetext.codeplex.com/SourceControl/changeset/view/65504#1129234
Here’s the full code so you can see it here. Remember, the latest source of the dotNetExt project will always have the latest source used within the project, and the code pasted below may become stale over time. <pre class="csharpcode">//Copyright (c) Chris Pietschmann 2012 () //All rights reserved. //Licensed under the GNU Library General Public License (LGPL) //License can be found here: http://www.codeplex.com/dotNetExt/license

using System.Collections; using System.Data.SqlClient; using System.Runtime.Serialization;

namespace TestProject { public enum SqlExceptionNumber : int { TimeoutExpired = -2, // Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding EncryptionNotSupported = 20, // The instance of SQL Server you attempted to connect to does not support encryption LoginError = 64, // A connection was successfully established with the server, but then an error occurred during the login process ConnectionInitialization = 233, // The client was unable to establish a connection because of an error during connection initialization process before login TransportLevelReceiving = 10053, // A transport-level error has occurred when receiving results from the server TransportLevelSending = 10054, // A transport-level error has occurred when sending the request to the server. EstablishingConnection = 10060, // A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible ProcessingRequest = 40143, // The service has encountered an error processing your request. Please try again. ServiceBudy = 40501, // The service is currently busy. Retry the request after 10 seconds. DatabaseOrServerNotAvailable = 40613 // Database ‘%.ls’ on server ‘%.ls’ is not currently available. Please retry the connection later. }

<span class="kwrd">public</span> <span class="kwrd">class</span> SqlExceptionHelper
{
    <span class="kwrd">public</span> <span class="kwrd">static</span> SqlException Generate(SqlExceptionNumber errorNumber)
    {
        <span class="kwrd">return</span> SqlExceptionHelper.Generate((<span class="kwrd">int</span>)errorNumber);
    }

    <span class="kwrd">public</span> <span class="kwrd">static</span> SqlException Generate(<span class="kwrd">int</span> errorNumber)
    {
        var ex = (SqlException)FormatterServices.GetUninitializedObject(<span class="kwrd">typeof</span>(SqlException));

        var errors = GenerateSqlErrorCollection(errorNumber);
        SetPrivateFieldValue(ex, <span class="str">&quot;_errors&quot;</span>, errors);

        <span class="kwrd">return</span> ex;
    }

    <span class="kwrd">private</span> <span class="kwrd">static</span> SqlErrorCollection GenerateSqlErrorCollection(<span class="kwrd">int</span> errorNumber)
    {
        var t = <span class="kwrd">typeof</span>(SqlErrorCollection);

        var col = (SqlErrorCollection)FormatterServices.GetUninitializedObject(t);
        
        SetPrivateFieldValue(col, <span class="str">&quot;errors&quot;</span>, <span class="kwrd">new</span> ArrayList());

        var sqlError = GenerateSqlError(errorNumber);
        var method = t.GetMethod(
            <span class="str">&quot;Add&quot;</span>,
            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance
            );        
        method.Invoke(col, <span class="kwrd">new</span> <span class="kwrd">object</span>[] { sqlError });

        <span class="kwrd">return</span> col;
    }

    <span class="kwrd">private</span> <span class="kwrd">static</span> SqlError GenerateSqlError(<span class="kwrd">int</span> errorNumber)
    {
        var sqlError = (SqlError)FormatterServices.GetUninitializedObject(<span class="kwrd">typeof</span>(SqlError));

        SetPrivateFieldValue(sqlError, <span class="str">&quot;number&quot;</span>, errorNumber);
        SetPrivateFieldValue(sqlError, <span class="str">&quot;message&quot;</span>, <span class="kwrd">string</span>.Empty);
        SetPrivateFieldValue(sqlError, <span class="str">&quot;procedure&quot;</span>, <span class="kwrd">string</span>.Empty);
        SetPrivateFieldValue(sqlError, <span class="str">&quot;server&quot;</span>, <span class="kwrd">string</span>.Empty);
        SetPrivateFieldValue(sqlError, <span class="str">&quot;source&quot;</span>, <span class="kwrd">string</span>.Empty);

        <span class="kwrd">return</span> sqlError;
    }

    <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">void</span> SetPrivateFieldValue(<span class="kwrd">object</span> obj, <span class="kwrd">string</span> field, <span class="kwrd">object</span> val)
    {
        var member = obj.GetType().GetField(
            field,
            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance
            );
        member.SetValue(obj, val);
    }
} }</pre>