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

发布于 2024-07-06 03:27:05 字数 400 浏览 13 评论 0原文

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

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

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

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

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

In my tests I need to test what happens when an OracleException is thrown (due to a stored procedure failure). I am trying to setup Rhino Mocks to

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

For whatever reason however, OracleException seems to be sealed with no public constructor. What can I do to test this?

Edit: Here is exactly what I'm trying to instantiate:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

满意归宿 2024-07-13 03:27:05

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

For oracle's managed data access (v 4.121.1.0) the constructor changed again

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, "", "", "" });
听风念你 2024-07-13 03:27:05

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

It seems that Oracle changed their constructors in later versions, therefore the solution above will not work.

If you only want to set the error code, the following will do the trick for 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 });
厌味 2024-07-13 03:27:05

操作方法如下:

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

感谢所有提供帮助的人,您已被投票

Here is how you do it:

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

Thanks to all that helped, you have been upvoted

一个人的夜不怕黑 2024-07-13 03:27:05

我正在使用 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 版本的客户端库。

谢谢,

查理

I'm using the Oracle.DataAccess.Client data provider client. I am having trouble constructing a new instance of an OracleException object, but it keeps telling me that there are no public constructors. I tried all of the ideas shown above and keep getting a null reference 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);

When debugging the test code, I always get a NULL value for 'ci'.

Has Oracle changed the library to not allow this? What am I doing wrong and what do I need to do to instantiate an OracleException object to use with NMock?

By the way, I'm using the Client library for version 10g.

Thanks,

Charlie

≈。彩虹 2024-07-13 03:27:05

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

new OracleException()

用。。。来

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

Use reflection to instantiate the OracleException object? Replace

new OracleException()

with

object[] args = ... ;
(OracleException)Activator.CreateInstance(typeof(OracleException), args)
人生戏 2024-07-13 03:27:05

使用反射来实例化 OracleException。 请参阅 这篇博文

Use reflection to instantiate OracleException. See this blog post

春花秋月 2024-07-13 03:27:05

您始终可以获得像这样的所有构造函数

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

For Oracle.DataAccess 4.112.3.0 这返回了 7 个构造函数

在此处输入图像描述

我想要的是列表中的第二个,它有 5 个参数,int,字符串,字符串,字符串,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);`

You can always get all the constructors like this

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

For Oracle.DataAccess 4.112.3.0 this returned 7 constructors

enter image description here

The one I wanted was the second one in the list which took 5 arguments, int, string, string, string, int. I was surprised by the fifth argument because in ILSpy it looked like this

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

So, to get the constructor I wanted I ended up using

ConstructorInfo constructorInfo =
  typeof(OracleException).GetConstructor(
    BindingFlags.NonPublic | BindingFlags.Instance,
    null,
    new Type[] { typeof(int), typeof(string), typeof(string), typeof(string), typeof(int) },
    null);`
巨坚强 2024-07-13 03:27:05

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

Good solution George. This also works for SqlException too:

        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

愿得七秒忆 2024-07-13 03:27:05

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

Can you write a trivial stored procedure that fails/errors each time, then use that to test?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文