单元测试/模拟静态事件处理程序,有哪些可用选项?

时间:2009-10-19 13:26:58

标签: c# unit-testing mocking

我完全清楚GC角度来看静态事件处理程序的“问题”所以我不是在寻找关于“不要使用静态事件”或类似内容的建议,在我的场景中这不是一个问题。

我有一个静态类,它声明了一个事件

public static event EventHandler<MyEventArgs> FilePickedUpFromStorage;

我有一个订阅此事件的客户端服务,并且我希望Mock /测试使用假的MyEventArgs触发的静态事件,以在客户端断言指定的处理工作。直截了当的......我遇到的问题是这个事件在静态类上是静态的。如果有人能提供任何帮助,我正在寻找关于处理这个问题的最佳方法的一些可靠指导。更改静态事件不是一个选项,包装它或任何其他魔法是......

谢谢!

3 个答案:

答案 0 :(得分:3)

由于您明确指出不能将事件从静态更改为实例,因此您可以查看TypeMock Isolator。它是一个模拟框架,可以通过重写IL代码来模拟无法模拟的东西。它不是IMO的最佳解决方案,但它可以帮助您在不改变代码的情况下希望您想要这种情况。

答案 1 :(得分:2)

您可以将静态事件保留为“旧版兼容性”,并为新(和可测试)代码提供更好的结构。

// legacy
public static class OldClass
{
  public static event EventHandler<MyEventArgs> FilePickedUpFromStorage;
}

// new interface for testability
public interface IBraveNewWorld
{
  event EventHandler<MyEventArgs> FilePickedUpFromStorage;
}

// new implementation
public class BraveNewWorld : IBraveNewWorld
{
  public event EventHandler<MyEventArgs> FilePickedUpFromStorage;
  public BraveNewWorld()
  {
    // MyHandler forwards the event
    OldClass.FilePickedUpFromStorage += MyHandler;
  }
}

// new testable user of the event.
public class TestableClass
{
  // here you can pass a mock or just an instance of BraveNewWorld
  public TestableClass(IBraveNewWorld x)
  {

  }
}

答案 2 :(得分:-2)

您正在测试班级对接收活动的回应。因此,大概你会担心你班上收到事件的方法的行为

public void OnHandler1(object sender, MyEventArgs e)

所以在你的测试中你不是直接调用那个方法吗?你可能需要嘲笑发送者对象,但是他是一个已知的类型,因为你是在施迫他使用他,所以你知道要嘲笑什么。

换句话说,为了测试你的课程,你可能根本不需要真正的事件来源。