dimanche 1 mai 2016

Testing long running/polling tasks using Visual Studio Unit Tests

I realize I should be compartmentalizing the following class into smaller classes and testing each function individually; however, this class is complex in a sense that it has to monitor a file system on a server and decide wether to restart a glitched windows service or email a support person to let them know the windows service is messed up. It's basically running on a timer and polling a few directories, keeping tabs on files entering via ftp and files leaving etc. The problem I'm having testing it is that fact that it uses timers and gets executed every timer elapsed event (1 second). As this is a unit test the unit test exits after the timer.Elapsed += Timer_Elapsed line. The code I want to test is on the elapsed event. I could in fact run this in a console app to test but I want to try and make an actual unit test for it.

Is there some way to keep a unit test running so that elapsed events will continue to run and thus be able to read Debug.WriteLine statement in the output window as the test runs?

 private Tasks.WindowsServiceTasks.MonitorCKEngine monitor;
    private Timer timer;
    private bool ckEngineMonitorFailure = false;

    [TestMethod]
    public void TestAllSystemsWorking()
    {
        timer = new Timer(1000);

        var testServiceController = new Common.Testing.ServiceController_Test("test1");
        var testServiceController2 = new Common.Testing.ServiceController_Test("test2");

        monitor = new Tasks.WindowsServiceTasks.MonitorCKEngine(new Common.Testing.EmailServices_Test(), new Common.Testing.IO_Test(),
            new[] { testServiceController, testServiceController2 });

        monitor.OnExecuting += Monitor_OnExecuting;
        monitor.OnStatusUpdate += Monitor_OnStatusUpdate;

        timer.Start();
        timer.Elapsed += Timer_Elapsed;
    }

    private void Timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        timer.Stop();
        if(ckEngineMonitorFailure == false)
        {
            monitor.Execute();
            timer.Start();
        }
    }

    private void Monitor_OnStatusUpdate(object sender, EventArgs e)
    {
        Debug.WriteLine(DateTime.Now + " ++ " +sender);

        if (sender.ToString().ToLower().Contains("restart failed") || sender.ToString().ToLower().Contains("cancelling process"))
        {
            ckEngineMonitorFailure = true;
        }
    }

    private bool Monitor_OnExecuting(object sender, System.ComponentModel.CancelEventArgs e)
    {
        if (ckEngineMonitorFailure)
        {
            e.Cancel = true;
            return false;
        }

        return true;
    }

Aucun commentaire:

Enregistrer un commentaire