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

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

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

无论出于何种原因,OracleException似乎都没有公共构造函数。 我该怎么做才能测试这个?

编辑:这正是我想要实例化的内容:

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

似乎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的托管数据访问(v 4.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 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 }); 

感谢所有帮助,你被投了赞成票

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

 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’的NULL值。

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

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

谢谢,

查理

使用reflection来实例化OracleException。 看到这篇博文

使用reflection来实例化OracleException对象? 更换

 new OracleException() 

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

你总能得到像这样的所有构造函数

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

对于Oracle.DataAccess 4.112.3.0,这返回了7个构造函数

在此处输入图像描述

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

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

好的解决方案George。 这也适用于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 } ); 

戴夫

你能写一个每次都失败/错误的普通存储过程,然后用它来测试吗?