简体   繁体   中英

How to unittest a global error handler?

I have the following function and I need to know how to write a UnitTest for it. (the HandleError function)

    public partial class App : Application
{
    public App()
    {
        this.Startup += App_Startup;
        Dispatcher.UnhandledException += HandleError;
    }
     private void HandleError(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        string exception = e.Exception.Message;
        MessageBox.Show(exception + "\"", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
        e.Handled = true;
    }
}

I am fairly new to UnitTest so i might not know as much.

So, there are good news and there are bad news. The good news - yes, you can unit test it, even in the free Visual Studio. The bad news - since you're using a static MessageBox.Show your unit test actually results in actual box showing.

Unit test code:

    [TestMethod]
    public void App_Handles_Exceptions()
    {
      var app = new App();
      var dapp = (DispatcherObject)app;
      var mi = typeof(Dispatcher).GetMethod("CatchException", BindingFlags.Instance | BindingFlags.NonPublic);
      var handled = (bool)mi.Invoke(dapp.Dispatcher, new object[] { new Exception("a") });

      Assert.IsTrue(handled);
    }

Now if you do happen to have an Enterprise edition of Visual Studio (sadly, even with 2017 it's required), you can use the Microsoft Fakes feature and then the test is completely isolated with no side effects:

[TestMethod]
public void App_Handles_Exceptions_WithFakes()
{
  using (ShimsContext.Create())
  {
    string usedMessage = null;
    string usedError = null;
    System.Windows.Fakes.ShimMessageBox.ShowStringStringMessageBoxButtonMessageBoxImage = (s, s1, arg3, arg4) =>
      {
        usedMessage = s;
        usedError = s1;
        return MessageBoxResult.OK;
      };

    var app = new App();
    var dapp = (DispatcherObject)app;
    var mi = typeof(Dispatcher).GetMethod("CatchException", BindingFlags.Instance | BindingFlags.NonPublic);
    var handled = (bool)mi.Invoke(dapp.Dispatcher, new object[] { new Exception("a") });

    Assert.IsTrue(handled);
    Assert.AreEqual("a\"", usedMessage);
    Assert.AreEqual("Error", usedError);
  }
}

This is the intro to Microsoft Fakes: https://msdn.microsoft.com/en-us/library/hh549175.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM