C# 如何在没有公共构造函数的情况下模拟/伪造/存根密封OracleException?

C# 如何在没有公共构造函数的情况下模拟/伪造/存根密封OracleException?,c#,.net,oracle,mocking,oracleclient,C#,.net,Oracle,Mocking,Oracleclient,在我的测试中,我需要测试在抛出OracleException(由于存储过程失败)时会发生什么。我正在尝试将Rhino Mock设置为 Expect.Call(....).Throw(new OracleException()); 然而,无论出于何种原因,OracleException似乎是密封的,没有公共构造函数。我能做些什么来测试这个 编辑:这里正是我试图实例化的内容: public sealed class OracleException : DbException { private

在我的测试中,我需要测试在抛出OracleException(由于存储过程失败)时会发生什么。我正在尝试将Rhino Mock设置为

Expect.Call(....).Throw(new OracleException());
然而,无论出于何种原因,OracleException似乎是密封的,没有公共构造函数。我能做些什么来测试这个

编辑:这里正是我试图实例化的内容:

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

您能否编写一个每次都失败/出错的简单存储过程,然后使用它进行测试?

使用反射来实例化OracleException对象?替换

new OracleException()


使用反射实例化OracleException。请参见以下方法:

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

多亏了这些帮助,你才被选为优秀的解决方案乔治。这也适用于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

我正在使用Oracle.DataAccess.Client数据提供程序客户端。我在构建OracleException对象的新实例时遇到困难,但它一直告诉我没有公共构造函数。我尝试了上面显示的所有想法,并不断得到一个空引用异常

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);
调试测试代码时,我总是为“ci”获取空值

Oracle是否已将库更改为不允许此操作?我做错了什么?我需要做什么来实例化OracleException对象以与NMock一起使用

顺便说一下,我正在使用10g版的客户端库

谢谢


Charlie

看来Oracle在以后的版本中更改了它们的构造函数,因此上述解决方案将无法工作

如果您只想设置错误代码,则以下操作将适用于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 });

对于oracle的托管数据访问(V4.121.1.0),构造函数再次更改

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

你总是可以得到所有这样的构造函数

ConstructorInfo[] all = typeof(OracleException).GetConstructors(
  BindingFlags.NonPublic | BindingFlags.Instance);`
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));
}
对于
Oracle.DataAccess
4.112.3.0,返回了7个构造函数

我想要的是列表中的第二个,它有5个参数,
int,string,string,string,int
。我对第五个论点感到惊讶,因为在ILSpy中它看起来是这样的

ConstructorInfo[] all = typeof(OracleException).GetConstructors(
  BindingFlags.NonPublic | BindingFlags.Instance);`
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));
}
所以,为了得到我想要的构造函数,我最终使用了

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

我不想每次都访问数据库!这似乎是可行的,我如何指定构造函数参数?Activator.CreateInstance(typeof(OracleException),new object[]{yourParams});我如何为ddtek 4.2.0.0做到这一点?我是refleciton的新手,无法识别任何构造函数