2008-09-23 7 views
9

In meinen Tests muss ich testen, was passiert, wenn eine OracleException ausgelöst wird (aufgrund eines Stored Procedures fehlgeschlagen). Ich versuche, Setup Rhino Mocks zuWie kann ich OracleException mit einem öffentlichen Konstruktor mock/fake/stub versiegeln?

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

Aus irgendeinem Grund jedoch OracleException scheint ohne öffentlichen Konstruktor abgedichtet werden. Was kann ich tun, um dies zu testen?

Edit: Hier ist genau das, was ich zu instanziieren versucht:

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

Antwort

3

Es scheint, dass Oracle in späteren Versionen ihrer Konstrukteure geändert, damit über die Lösung wird nicht funktionieren.

Wenn Sie nur den Fehlercode gesetzt werden soll, wird die folgende den Trick für 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 }); 
-1

Können Sie eine triviale gespeicherte Prozedur schreiben, die/Fehler jedes Mal ausfällt, dann verwenden, zu testen?

+2

Ich will nicht zu haben, um die Datenbank zu treffen jedes Mal! –

2

Verwenden Sie Reflektion, um das OracleException-Objekt zu instanziieren? Ersetzen

new OracleException() 

mit

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

Dies scheint wie es funktioniert, wie gebe ich Konstruktor Argumente? –

+0

Activator.CreateInstance (typeof (OracleException), neues Objekt [] {yourParams}); –

+0

Pfui, funktioniert nicht für private Parameter –

3

Verwenden Reflexion OracleException zu instanziiert. Siehe this blog post

5

Hier ist, wie Sie es tun:

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

Vielen Dank an alle, die dazu beigetragen haben Sie

1

Gute Lösung George upvoted worden. Dies funktioniert auch für SqlException zu:

 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

3

ich den Oracle.DataAccess.Client Data Provider Client bin mit. Ich habe Probleme beim Erstellen einer neuen Instanz eines OracleException-Objekts, aber es sagt mir immer wieder, dass es keine öffentlichen Konstruktoren gibt. Ich habe alle oben gezeigten Ideen ausprobiert und bekomme weiterhin eine Null-Referenz-Ausnahme.

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

Beim Debuggen des Testcodes bekomme ich immer einen NULL-Wert für 'ci'.

Hat Oracle die Bibliothek geändert, um dies zu verhindern? Was mache ich falsch und was muss ich tun, um ein OracleException-Objekt für die Verwendung mit NMock zu instanziieren?

Übrigens verwende ich die Client-Bibliothek für Version 10g.

Danke,

Charlie

5

Für verwaltete Datenzugriff des Orakels (v 4.121.1.0) der Konstruktor geändert wieder

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

Wie mache ich es für ddtek 4.2.0.0? Ich bin neu in refleciton und ich kann keine Konstruktoren identifizieren – Tomas

2

Sie immer alle Konstrukteure wie diese

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

Für Oracle.DataAccess 4.112.3.0 diese zurück bekommen 7 Konstrukteurs

enter image description here

Der, den ich gesucht war der zweite in der Liste, der 5 Argumente, int, string, string, string, int, nahm. Ich war von dem fünften Argumente überrascht, weil in ILSpy es sah aus wie diese

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

, also den Konstruktor zu bekommen Ich wollte ich

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