正在验证执行的事件处理程序代码

本文关键字:事件处理 程序 代码 执行 验证 | 更新日期: 2023-09-27 18:25:22

我有与此非常相似的代码,但无法确定如何测试是否发生了事件处理程序。

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
    }

正在验证执行的事件处理程序代码

我能想到的最简单的方法就是在测试方法中添加自己的处理程序,我认为这应该足够了吗?

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

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

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

您需要注入事件处理程序调用后调用的任何对象的mock并对其进行验证。您的注释说您无法测试base。OnOutput,但在我看来,这正是你需要做的。

基本上,对方法被调用的事实的测试不是有效的测试用例,您应该测试方法背后的逻辑/行为。显然,对于给定的事件处理程序,没有什么可测试的,这就是为什么任务看起来并不琐碎。

试着用几个词来表述你要测试什么,哪个测试用例。例如

MyClass将状态切换到State==Hit,同时FileSystem.EventHit事件。

要做到这一点,您可能需要在MyClass中使用一个标志来指示发生了该事件。我知道,这只是为了进行测试,但有时有这样的东西是很好的。