Udostępnij za pośrednictwem


Mocking SQLException

I'm working on a presentation about Testing, and one of the technics I would like to show is MockObjects.

One of the mock objects I want to create is a DataAccess Layer, and this one should throw SqlExceptions, however the SqlException class is sealed and has no public constructor.

 

I found a comment about it here: https://www.taylor.se/blog/2006/06/09/mocking-sqlexception/

But the implementation does not work with .Net2, so I have to refactor the code to create a SqlExceptionCreator, and here it is:

 

using System;

using System.Data.SqlClient;

using System.Reflection;

using System.Runtime.Serialization;

public class SqlExceptionCreator

{

    public static SqlException CreateSqlException(string errorMessage, int errorNumber)

    {

        SqlErrorCollection collection = GetErrorCollection();

        SqlError error = GetError(errorNumber, errorMessage);

        MethodInfo addMethod = collection.GetType().

            GetMethod("Add", BindingFlags.NonPublic | BindingFlags.Instance);

       addMethod.Invoke(collection, new object[] { error });

        Type[] types = new Type[] { typeof(string), typeof(SqlErrorCollection) };

        object[] parameters = new object[] { errorMessage, collection };

        ConstructorInfo constructor = typeof(SqlException).

            GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, types, null);

        SqlException exception = (SqlException)constructor.Invoke(parameters);

        return exception;

    }

    private static SqlError GetError(int errorCode, string message)

    {

        object[] parameters = new object[] {

            errorCode, (byte)0, (byte)10, "server", message, "procedure", 0 };

        Type[] types = new Type[] {

            typeof(int), typeof(byte), typeof(byte), typeof(string), typeof(string),

            typeof(string), typeof(int) };

        ConstructorInfo constructor = typeof(SqlError).

            GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, types, null);

        SqlError error = (SqlError)constructor.Invoke(parameters);

        return error;

    }

    private static SqlErrorCollection GetErrorCollection()

    {

        ConstructorInfo constructor = typeof(SqlErrorCollection).

            GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);

        SqlErrorCollection collection = (SqlErrorCollection)constructor.Invoke(new object[] { });

        return collection;

    }

}

Comments

  • Anonymous
    November 26, 2006
    Is it considered good practice for the DAL to expose implementation concerns like SqlException? What if we were working with Oracle? Does our BL have to be aware of this?

  • Anonymous
    November 26, 2006
    This is just a demo about MockObjects, I'm using a TableAdapter to read/write from a DB, and I would like to show how to simulate this behavior inside the mock.

  • Anonymous
    May 14, 2015
    Does not work with 4,.5 constructor is always null