11

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

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

然而,无论出于何种原因,OracleException 似乎被密封而没有公共构造函数。我能做些什么来测试这个?

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

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

9 回答 9

8

对于 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, "", "", "" });
于 2014-10-09T22:22:20.257 回答
6

这是您的操作方法:

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

感谢所有帮助,您已被投票

于 2008-09-23T17:30:04.297 回答
4

使用反射来实例化 OracleException。请参阅此博客文章

于 2008-09-23T16:48:01.027 回答
4

我正在使用 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' 的 NULL 值。

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

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

谢谢,

查理

于 2010-07-01T17:10:09.947 回答
4

似乎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 });
于 2011-05-06T08:03:01.007 回答
3

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

new OracleException()

object[] args = ... ;
(OracleException)Activator.CreateInstance(typeof(OracleException), args)
于 2008-09-23T16:45:36.323 回答
3

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

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

对于Oracle.DataAccess4.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);`
于 2017-06-29T09:03:18.907 回答
2

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

-戴夫

于 2009-06-17T03:22:46.660 回答
-1

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

于 2008-09-23T16:44:49.507 回答