ChrisM
ChrisM

Reputation: 1168

How to make Application.Run() testable

I am currently writing system tests for a legacy windows forms application.

In my test, I call the Program.Main() method, which in turn calls Application.Run(new MainForm()); at some point.

Is there a way to replace Application.Run() with something that I can control?

Specifically, I need to be able to stop the execution and catch unhandled exceptions.

Upvotes: 1

Views: 133

Answers (2)

Kostya
Kostya

Reputation: 849

  1. To "stop the execution", you can ask Main thread to exit by calling Application.ExitThread() and in dreadful situations when it does't respond you may kill the Main thread with .Abort() as a last resort.
  2. The exceptions won't be automatically collected for you anywhere, but you can catch them in a process of testing using

Application.ThreadExceptionHandler

AppDomain.CurrentDomain.UnhandledException

  1. Testing a real-life app without Application might be a problem because people often do some tricks by calling Application.DoEvents(..) and doing other stuff with messages pump.

Upvotes: 1

John Wu
John Wu

Reputation: 52240

You could modify Program.Main to accept a form as an input parameter, with a default of MainForm. Reference types can't have non-null defaults but we can accomplish the same thing by using two prototypes:

class Program
{
    //Normal entry point
    static public void Main()
    {
        Main(new MainForm());
    }

    //Internal & test entry point
    static public void Main(Form form)
    {
        DoSomeSetup();
        Application.Run(form);
    }
}

When you run the program in the normal way, it'll use a MainForm.

But when you run it from your test project, you can call it like this:

Program.Main(new FormICanControl());

And then you can control it.

//Arrange
var t = new TestForm();

//Act
Program.Main(t);
t.ExecuteSomeTest();

//Assert
Assert.AreEqual(t.ResultCode, 0, "Test failed.");

Upvotes: 1

Related Questions