2012-02-20 60 views
3

我的代码非常类似于此,但无法计算出我如何测试事件处理程序是否发生。验证执行的事件处理程序代码

public class MyClass : MyAbstractClass 
{ 
    IFileSystem FileSystem; 

    public MyClass(IFileSystem myFileSys) 
    { 
    FileSystem = myFileSys; 
    FileSystem.EventHit += new EventHandler(FileSystem_EventHit); 
    } 

    public void FileSystem_EventHit(object sender, EventArgs e) 
    { 
    //Testing base.OnOutput is not possible which I wont go into 
    base.OnOutput("EventHit"); 
    } 
} 

测试代码是在这里:

[Test] 
    public void DoSomething_WhenCalled_EventFired() 
    { 
     var mock = new Moq.Mock<IFileSystem>(); 

     MyClass plugin = new MyClass (mock.Object); 

     mock.Object.DoSomething(); 

     mock.Raise(x => x.EventHit += null, new EventArgs()); 

     //Verify/Assert that MyClass handled and did something in the event handler 

    } 
+0

你可以提供详细信息WRT base.OnOutput,也许它是可测试的? – 2012-02-20 13:47:12

+0

MyAbstractClass是遗留的,因此MyClass也是遗留下来的,因此它很混乱,需要大量的设置才能测试,所以我希望有一些方法可以测试,而无需验证base.OnOutput – Jon 2012-02-20 13:51:35

+0

常见的场景;回顾性编写单元测试。我不知道任何捷径。每当遇到这种情况,我都会重新构造代码,以便它可以进行单元测试。 – 2012-02-20 13:56:42

回答

0

由于验证事件处理程序中的某些内容意味着尝试测试遗留代码,所以我选择的选项是测试事件是从具体类型中触发的事件,而不是模拟。

[Test] 
public void DoSomething_WhenCalled_EventFired() 
{ 

    FileSystem fs = new FileSystem(mock.Object, timerMock.Object); 

    bool WasItHit = false; 
    fs.EventHit += delegate { WasItHit = true; }; 

    fs.DoSomething(); //This should call the event 

    Assert.IsTrue(WasItHit); 
} 
1

我能想到的最简单的方法是只需添加自己的处理程序中的测试方法,这应该足够我会想到什么?

[Test] 
    public void DoSomething_WhenCalled_EventFired() 
    { 
     var mock = new Moq.Mock<IFileSystem>(); 
     bool isHit = false; 

     mock.EventHit += (s, e) => 
     { 
      isHit = true; 
     }; 

     MyClass plugin = new MyClass (mock.Object); 

     mock.Object.DoSomething(); 

     mock.Raise(x => x.EventHit += null, new EventArgs()); 

     Assert.IsTrue(isHit); 

    } 
+1

这将声明模拟引发的事件,它不会证实MyClass.FileSystem_EventHit被调用或验证发生了什么结果。 – 2012-02-20 13:45:48

0

您需要为事件处理程序调用的结果注入任何被调用的模拟并进行验证。你的评论说你不能测试base base.OnOutput,但在我看来,这正是你需要做的。

+0

这就是问题所在!抽象类和大多数MyClass是遗留代码,它是一个噩梦来测试 – Jon 2012-02-20 13:50:00

0

基本测试调用方法的事实不是有效的测试用例,您应该测试方法背后的逻辑/行为。显然,对于给定的事件处理函数,没有什么可以测试的,这就是为什么一个任务看起来不平凡。

试试用几句话写出你想要测试什么样的测试用例。例如

MyClass的切换的状态下进入State==Hit同时 FileSystem.EventHit事件。

+0

我同意,但MyClass充当输入/输出类的类,所以东西进来调用DoSomething,它会触发事件并执行输出 – Jon 2012-02-20 13:53:19

+0

它是什么做输出,乔恩?如果是另一个依赖项,那么模拟MyClass或基类用来执行输出的依赖项,并验证是否使用该依赖项进行了输出调用。 – 2012-02-20 14:02:51

+0

是的,我会做的,但它的所有遗留代码,是一个噩梦设置 – Jon 2012-02-20 14:13:24

0

要做到这一点,您可能需要MyClass中的一个标志来指示事件发生。我知道,这只是为了运行测试的目的,但有时候有这样的好事。

相关问题