Comment puis-je simuler / falsifier / stub scellé OracleException sans constructeur public?
-
02-07-2019 - |
Question
Lors de mes tests, je dois vérifier ce qui se produit lorsqu'une exception OracleException est levée (en raison d'un échec de la procédure stockée). J'essaie de configurer Rhino Mocks pour
Expect.Call(....).Throw(new OracleException());
Pour une raison quelconque, OracleException semble être scellé sans constructeur public. Que puis-je faire pour tester cela?
Modifier: Voici exactement ce que j'essaie d'instancier:
public sealed class OracleException : DbException {
private OracleException(string message, int code) { ...}
}
La solution
Il semble qu'Oracle ait modifié ses constructeurs dans les versions ultérieures. Par conséquent, la solution ci-dessus ne fonctionnera pas.
Si vous souhaitez uniquement définir le code d'erreur, voici ce qui convient pour 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 });
Autres conseils
Pour l'accès aux données gérées d'Oracle (v 4.121.1.0), le constructeur a changé à nouveau
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, "", "", "" });
Voici comment vous le faites:
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 });
Merci à tout ce qui vous a aidé, vous avez été voté
J'utilise le client du fournisseur de données Oracle.DataAccess.Client. Je ne parviens pas à créer une nouvelle instance d'un objet OracleException, mais le système me répète qu'il n'y a pas de constructeur public. J'ai essayé toutes les idées présentées ci-dessus et je continue à avoir une exception de référence nulle.
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);
Lors du débogage du code de test, j'obtiens toujours une valeur NULL pour 'ci'.
Oracle a-t-il modifié la bibliothèque pour ne pas permettre cela? Qu'est-ce que je fais de travers et que dois-je faire pour instancier un objet OracleException à utiliser avec NMock?
Au fait, j'utilise la bibliothèque client pour la version 10g.
Merci,
Charlie
Utilisez la réflexion pour instancier OracleException. Voir cet article de blog
Utilisez-vous la réflexion pour instancier l'objet OracleException? Remplacer
new OracleException()
avec
object[] args = ... ;
(OracleException)Activator.CreateInstance(typeof(OracleException), args)
Vous pouvez toujours obtenir tous les constructeurs comme celui-ci
ConstructorInfo[] all = typeof(OracleException).GetConstructors(
BindingFlags.NonPublic | BindingFlags.Instance);`
Pour Oracle.DataAccess
4.112.3.0, 7 constructeurs ont été renvoyés
Celui que je voulais était le deuxième de la liste qui prenait 5 arguments, int, chaîne, chaîne, chaîne, int,
. J'ai été surpris par le cinquième argument car dans ILSpy, cela ressemblait à ceci
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));
}
Donc, pour obtenir le constructeur que je voulais, j'ai fini par utiliser
ConstructorInfo constructorInfo =
typeof(OracleException).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new Type[] { typeof(int), typeof(string), typeof(string), typeof(string), typeof(int) },
null);`
Bonne solution George. Cela fonctionne aussi pour 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
Pouvez-vous écrire une procédure stockée triviale qui échoue / échoue à chaque fois, puis utilisez-la pour tester?