Domanda

Nei miei test ho bisogno di testare cosa succede quando viene generata una OracleException (a causa di un errore della procedura memorizzata). Sto cercando di impostare Rhino Mocks su

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

Per qualunque motivo, comunque, OracleException sembra essere sigillata senza alcun costruttore pubblico. Cosa posso fare per testarlo?

Modifica: Ecco esattamente quello che sto cercando di creare un'istanza:

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

Soluzione

Sembra che Oracle abbia cambiato i costruttori nelle versioni successive, quindi la soluzione sopra non funzionerà.

Se vuoi solo impostare il codice di errore, il seguente farà il trucco per 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 });

Altri suggerimenti

Per l'accesso ai dati gestiti di Oracle (v 4.121.1.0) il costruttore è stato nuovamente modificato

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

Ecco come lo fai:

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

Grazie a tutto ciò che ti ha aiutato, sei stato votato

Sto utilizzando il client provider di dati Oracle.DataAccess.Client. Ho problemi a costruire una nuova istanza di un oggetto OracleException, ma continua a dirmi che non ci sono costruttori pubblici. Ho provato tutte le idee mostrate sopra e continuo a ricevere un'eccezione di riferimento null.

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

Quando eseguo il debug del codice di test, ottengo sempre un valore NULL per 'ci'.

Oracle ha modificato la libreria per non consentire questo? Cosa sto facendo di sbagliato e cosa devo fare per creare un'istanza di un oggetto OracleException da utilizzare con NMock?

A proposito, sto usando la libreria Client per la versione 10g.

Grazie,

Charlie

Usa la riflessione per creare un'istanza di OracleException. Vedi questo post sul blog

Utilizzare la riflessione per creare un'istanza dell'oggetto OracleException? Sostituire

new OracleException()

con

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

Puoi sempre ottenere tutti i costruttori in questo modo

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

Per Oracle.DataAccess 4.112.3.0 questo ha restituito 7 costruttori

 inserisci qui la descrizione dell'immagine

Quello che volevo era il secondo nell'elenco che prendeva 5 argomenti, int, string, string, string, int . Sono rimasto sorpreso dal quinto argomento perché in ILSpy sembrava così

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

Quindi, per ottenere il costruttore che volevo ho finito con

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

Buona soluzione George. Questo funziona anche per 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

Puoi scrivere una banale stored procedure che fallisce / errori ogni volta, quindi usarla per testare?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top