如何创建具有私有构造函数的类型实例以进行单元测试?

发布于 2024-11-30 12:19:08 字数 386 浏览 0 评论 0原文

我需要对响应 System.IO.Ports.SerialPort 的 SerialDataReceived 事件的事件处理程序进行单元测试。该事件处理程序具有签名,

void SerialDataReceived(object sender, SerialDataReceivedEventArgs e)

因此当我的单元测试调用该方法时,它需要一个 SerialDataReceivedEventArgs 实例。但该对象有一个私有构造函数。那么如何将 SerialDataReceivedEventArgs 传递到该方法中呢?

我确信我一定在这里错过了一项明显的技术,我已经度过了漫长的一天......请问有什么建议吗?

I need to unit test an event handler that responds to the SerialDataReceived event of System.IO.Ports.SerialPort. This event handler has the signature

void SerialDataReceived(object sender, SerialDataReceivedEventArgs e)

So when my unit test calls into the method, it needs a SerialDataReceivedEventArgs instance. But that object has a private constructor. So how do I get a SerialDataReceivedEventArgs to pass into the method?

I'm sure I must be missing an obvious technique here, I have had a long day... Any advice please?

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

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

发布评论

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

评论(3

月竹挽风 2024-12-07 12:19:08

您可以使用反射创建所需类型的实例:

var args = typeof(SerialDataReceivedEventArgs)
  .GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new [] { typeof(SerialData) }, null)
  .Invoke(new object[] { SerialData.Chars });

You can create an instance of the desired type using reflection:

var args = typeof(SerialDataReceivedEventArgs)
  .GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new [] { typeof(SerialData) }, null)
  .Invoke(new object[] { SerialData.Chars });
画▽骨i 2024-12-07 12:19:08

您不能直接使用私有构造函数创建类的实例。您可以使用反射来做到这一点,但这是一个非常糟糕的解决方案。

You can't create instances of classes with private constructors directly. You could use reflection to do it, but that is a pretty nasty solution.

扬花落满肩 2024-12-07 12:19:08

我最终重构了我的代码以消除私有构造函数,如下所示:

    private void HandleSerialDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialDataReceived(sender, e.EventType);
    }

    /// <summary>
    ///   This method executes in response to the <see cref="ISerialPort.DataReceived"/> event
    ///   via <see cref="HandleSerialDataReceived"/> and is called on its own worker thread.
    /// </summary>
    internal void SerialDataReceived(object sender, SerialData eventType)
    {
     ...
    }

现在我可以对 SerialDataReceived 进行单元测试,并直接向其传递 SerialData 参数。

但是,我认为我更喜欢 Alexander 的解决方案,因为它不需要我重构我的生产代码。

I eventually refactored my code to eliminate the private constructor, like this:

    private void HandleSerialDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialDataReceived(sender, e.EventType);
    }

    /// <summary>
    ///   This method executes in response to the <see cref="ISerialPort.DataReceived"/> event
    ///   via <see cref="HandleSerialDataReceived"/> and is called on its own worker thread.
    /// </summary>
    internal void SerialDataReceived(object sender, SerialData eventType)
    {
     ...
    }

So now I can do my unit testing on SerialDataReceived and pass it the SerialData parameter directly.

However, I think I prefer Alexander's solution because it doesn't require me to re-factor my production code.

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