Pregunta

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 alguna razón, OracleException parece estar sellada sin ningún constructor público.¿Qué puedo hacer para probar esto?

Editar: Esto es exactamente lo que estoy tratando de crear una instancia:

public sealed class OracleException : DbException {
  private OracleException(string message, int code) { ...}
}
¿Fue útil?

Solución

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

Si solo desea configurar el código de error, lo siguiente funcionará 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 });

Otros consejos

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, "", "", "" });

Así es como se hace:

    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.

Estoy usando el cliente proveedor de datos Oracle.DataAccess.Client.Tengo problemas para construir una nueva instancia de un objeto OracleException, pero sigue diciéndome que no hay constructores públicos.Probé todas las ideas que se muestran arriba y sigo 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 usarlo con NMock?

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

Gracias,

charlie

Utilice la reflexión para crear una instancia de OracleException.Ver esta publicación de blog

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

new OracleException()

con

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

Siempre puedes conseguir 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

enter image description here

El que quería era el segundo de la lista que tenía 5 argumentos, int, string, string, string, int.Me sorprendió el quinto argumento porque en ILSpy se veía así

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);`

Buena solución Jorge.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

¿Puedes escribir un procedimiento almacenado trivial que falle/error cada vez y luego usarlo para realizar pruebas?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top