c# - 在 UnitTest 期间将 BeginInvoke 关闭委托(delegate)类型时需要帮助

标签 c# unit-testing delegates moles

在我的类中,我声明了一个委托(delegate)类型,我正在创建它的一个实例,然后调用该实例的 BeginInvoke:

public class ClassA
{
    ...
    public delegate bool MyDelegate(int x);
    ...
    public void MethodA()
    {
        ...
        var myDelegate = new MyDelegate(Foo);
        myDelegate.BeginInvoke(...);
        ...
    }
    ...
}

在为 MethodA 编写单元测试时,我实际上并不希望调用 BeginInvoke。我想要做的是使用 Moles 框架来监视 BeginInvoke 调用。通常情况下,我会尝试

MMyDelegate.AllInstances.BeginInvoke... = (...) => { /* something here */ }

但我无法让鼹鼠为 MyDelegate 类型生成任何内容。

根据http://msdn.microsoft.com/en-us/library/system.delegate.aspx ,“公共(public)语言运行时为每个委托(delegate)类型提供 BeginInvoke 和 EndInvoke 方法”。如果是这种情况,并且 BeginInvoke 甚至不是 Delegate 类中的方法(由 CLR 提供),是否有可能对它进行监视?还有其他人有幸从委托(delegate)类型中剔除 BeginInvoke 吗?

最佳答案

我不太了解 Microsoft Moles,但我尝试使用 Microsoft Fakes 实现相同的目标(实际上,这是 Visual Studio 2012 Premium 和 Ultimate 中内置的 Microsoft Moles 的继承者)。

当我尝试构建 Fake 程序集(知道 Microsoft 称之为 Fakes 和 Shims,而不是 Moles 和 Stubs)时,我收到以下警告:

Warning 1   Cannot generate stub for AssemblyUnderTest.FooDelegate: type is sealed. d:\Sources\Projects\PlayingWithMoles\PlayingWithMoles\Fakes\AssemblyUnderTest.fakes
Warning 2   Cannot generate shim for AssemblyUnderTest.FooDelegate: type is a delegate. d:\Sources\Projects\PlayingWithMoles\PlayingWithMoles\Fakes\AssemblyUnderTest.fakes

(要获得此警告,您应该关闭 fakes 配置文件中的附加诊断(我不确定 Fakes 和 Moles 中的格式是否相同):

<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/" **Diagnostic="true"**>
  <Assembly Name="AssemblyUnderTest"/>
</Fakes>

但是可惜的是,这个警告清楚地表明我们不能这样做。但我们可以通过转移到另一个异步 API 来完全避免这个问题,例如 Task Parallel Library a.k.a. TPL .

Task(或Task of T)对象本身委托(delegate)异步操作作为第一类对象,允许您将此“异步操作”存储在字段中,返回它来自方法或传递它。这大大提高了可测试性,因为您可以轻松地用假的实现来模拟您的实现:

class SomeService
{
  Task<string> GetSomeResult()
  {
    // Performing long-running operation to obtain the result
  }
}

class YourServiceConsumer
{
  private void YourMethod()
  {
     Task<string> task = service.GetSomeResult();
  }
}

您可以使用单独的接口(interface)轻松提取依赖项并将其注入(inject)到您的 YourServiceConsumer 中,或者使用 Microsoft Moles(或 Microsoft Fakes)伪造它,而无需添加其他层。

关于c# - 在 UnitTest 期间将 BeginInvoke 关闭委托(delegate)类型时需要帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13630929/

相关文章:

ios - 从 super View iOS 中删除 View

c# - 在 Xamarin 移动应用程序中显示存储在 Azure 存储中的 Blob/照片

c# - 抓取 htmlagilitypack

c# - 未找到匹配项时从 List<> 返回默认值

angularjs - 使用 Node.js、Gulp.js 和 Mocha 对 AngularJS Controller 进行单元测试

c# - 用 C# 编写全局自定义事件

c# - 将导航 url 设置为动态超链接

javascript - 没有 specRunner.html 的 Jasmine 规范 - JS 依赖

maven - Maven构建脚本

c# - 处理任何类型的方法