oracledatareader odp net data connectionstring conexion cadena c# .net oracle mocking oracleclient

c# - odp - ¿Cómo puedo simular/falsificar/archivar OracleException sellado sin un constructor público?



oracledatareader c# (9)

En mis pruebas, necesito probar qué sucede cuando se lanza una OracleException (debido a una falla en el procedimiento almacenado). Estoy intentando configurar Rhino Mocks para

Expect.Call(....).Throw(new OracleException());

Sin embargo, por cualquier motivo, OracleException parece estar sellada sin un constructor público. ¿Qué puedo hacer para probar esto?

Editar: Aquí es exactamente lo que intento crear una instancia:

public sealed class OracleException : DbException { private OracleException(string message, int code) { ...} }


¿Puedes escribir un procedimiento almacenado trivial que falle / errores cada vez, luego usarlo para probar?


Así es como lo haces:

ConstructorInfo ci = typeof(OracleException).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] {typeof(string), typeof(int)}, null); var c = (OracleException)ci.Invoke(new object[] { "some message", 123 });

Gracias a todos los que ayudaron, has sido votado


Buena solución George. Esto también funciona para SqlException:

ConstructorInfo ci = typeof( SqlErrorCollection ).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null ); SqlErrorCollection errorCollection = (SqlErrorCollection) ci.Invoke(new object[]{}); ci = typeof( SqlException ).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof( string ), typeof( SqlErrorCollection ) }, null ); return (SqlException) ci.Invoke( new object[] { "some message", errorCollection } );

-dave


Estoy usando el cliente del proveedor de datos Oracle.DataAccess.Client. Tengo problemas para construir una nueva instancia de un objeto OracleException, pero me sigue diciendo que no hay constructores públicos. Intenté todas las ideas que se muestran arriba y continúo obteniendo una excepción de referencia nula.

object[] args = { 1, "Test Message" }; ConstructorInfo ci = typeof(OracleException).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, System.Type.GetTypeArray(args), null); var e = (OracleException)ci.Invoke(args);

Al depurar el código de prueba, siempre obtengo un valor NULL para ''ci''.

¿Oracle ha cambiado la biblioteca para no permitir esto? ¿Qué estoy haciendo mal y qué debo hacer para crear una instancia de un objeto OracleException para usar con NMock?

Por cierto, estoy usando la biblioteca de cliente para la versión 10g.

Gracias,

Charlie


Para el acceso a datos administrados de Oracle (v 4.121.1.0) el constructor cambió nuevamente

var ci = typeof(OracleException).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(int), typeof(string), typeof(string), typeof(string) }, null); var c = (OracleException)ci.Invoke(new object[] { 1234, "", "", "" });


Parece que Oracle cambió sus constructores en versiones posteriores, por lo tanto, la solución anterior no funcionará.

Si solo quiere establecer el código de error, lo siguiente será el truco para 2.111.7.20:

ConstructorInfo ci = typeof(OracleException) .GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(int) }, null ); Exception ex = (OracleException)ci.Invoke(new object[] { 3113 });


Siempre puedes obtener todos los constructores como este

ConstructorInfo[] all = typeof(OracleException).GetConstructors( BindingFlags.NonPublic | BindingFlags.Instance);`

Para Oracle.DataAccess 4.112.3.0 esto devolvió 7 constructores

El que yo quería era el segundo en la lista que tomó 5 argumentos, int, string, string, string, int . Me sorprendió el quinto argumento porque en ILSpy parecía que esto

internal OracleException(int errCode, string dataSrc, string procedure, string errMsg) { this.m_errors = new OracleErrorCollection(); this.m_errors.Add(new OracleError(errCode, dataSrc, procedure, errMsg)); }

Entonces, para obtener el constructor que quería, terminé usando

ConstructorInfo constructorInfo = typeof(OracleException).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(int), typeof(string), typeof(string), typeof(string), typeof(int) }, null);`



Use la reflexión para crear una instancia del objeto OracleException? Reemplazar

new OracleException()

con

object[] args = ... ; (OracleException)Activator.CreateInstance(typeof(OracleException), args)