Skip to content

Instantly share code, notes, and snippets.

@timabell
Created May 30, 2014 21:32
Show Gist options
  • Save timabell/672719c63364c497377f to your computer and use it in GitHub Desktop.
Save timabell/672719c63364c497377f to your computer and use it in GitHub Desktop.
Workaround completely test-unfriendly sql error classes
using System.Data.SqlClient;
using System.Reflection;
namespace HorribleThingsInHere
{
/// <summary>
/// Workaround completely test-unfriendly sql error classes.
/// Copy-paste from http://stackoverflow.com/a/1387030/10245
/// Adjusted with updates in comments
/// </summary>
class SqlExceptionMocker
{
private static T Construct<T>(int ctorIndex, params object[] p)
{
var ctors = typeof (T).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
var ctor = ctors[ctorIndex];
return (T)ctor.Invoke(p);
}
public static SqlException MakeSqlException(int errorNumber)
{
var collection = Construct<SqlErrorCollection>(0);
var error = Construct<SqlError>(1, errorNumber, (byte) 2, (byte) 3, "server name", "This is a Mock-SqlException", "proc", 100);
typeof (SqlErrorCollection)
.GetMethod("Add", BindingFlags.NonPublic | BindingFlags.Instance)
.Invoke(collection, new object[] {error});
var e = typeof (SqlException)
.GetMethod("CreateException", BindingFlags.NonPublic | BindingFlags.Static, null, CallingConventions.ExplicitThis, new[] {typeof (SqlErrorCollection), typeof (string)}, new ParameterModifier[] {})
.Invoke(null, new object[] {collection, "7.0.0"}) as SqlException;
return e;
}
}
}
@shadow1runner
Copy link

Hi, after upgrading to .NET 4.5.2 it seems that the order of the returned constructors might have changed, this works quite fine for me:

private static T Construct<T>(params object[] p)
{
    return (from ctor in typeof (T).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)
            where ctor.GetParameters().Count() == p.Count()
            select (T) ctor.Invoke(p)).Single();
}

@dotnetchris
Copy link

Check out @martinjw's fork for a copy and paste ready source: https://gist.github.com/martinjw/668700c8d199312dad7d

@angularsen
Copy link

On .NET 4.7.2 I had to use this line:
var error = Construct<SqlError>(errorNumber, (byte) 2, (byte) 3, "server name", "This is a Mock-SqlException", "proc", 100, 0u);

There seems to be a new UInt32 parameter at the end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment