Unit Testing an Event Firing From a Thread
        Posted  
        
            by Dougc
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Dougc
        
        
        
        Published on 2010-02-25T20:10:40Z
        Indexed on 
            2010/04/22
            18:53 UTC
        
        
        Read the original article
        Hit count: 265
        
I'm having a problem unit testing a class which fires events when a thread starts and finishes. A cut down version of the offending source is as follows:
public class ThreadRunner
{
    private bool keepRunning;
    public event EventHandler Started;
    public event EventHandler Finished;
    public void StartThreadTest()
    {
        this.keepRunning = true;
        var thread = new Thread(new ThreadStart(this.LongRunningMethod));
        thread.Start();
    }
    public void FinishThreadTest()
    {
        this.keepRunning = false;
    }
    protected void OnStarted()
    {
        if (this.Started != null)
            this.Started(this, new EventArgs());
    }
    protected void OnFinished()
    {
        if (this.Finished != null)
            this.Finished(this, new EventArgs());
    }
    private void LongRunningMethod()
    {   
        this.OnStarted();
        while (this.keepRunning)
            Thread.Sleep(100);
        this.OnFinished();
    }
}
I then have a test to check that the Finished event fires after the LongRunningMethod has finished as follows:
[TestClass]
public class ThreadRunnerTests
{
    [TestMethod]
    public void CheckFinishedEventFiresTest()
    {
        var threadTest = new ThreadRunner();
        bool finished = false;
        object locker = new object();
        threadTest.Finished += delegate(object sender, EventArgs e)
        {
            lock (locker)
            {
                finished = true;
                Monitor.Pulse(locker);
            }
        };
        threadTest.StartThreadTest();
        threadTest.FinishThreadTest();
        lock (locker)
        {
            Monitor.Wait(locker, 1000);
            Assert.IsTrue(finished);
        }
    }
}
So the idea here being that the test will block for a maximum of one second - or until the Finish event is fired - before checking whether the finished flag is set.
Clearly I've done something wrong as sometimes the test will pass, sometimes it won't.  Debugging seems very difficult as well as the breakpoints I'd expect to be hit (the OnFinished method, for example) don't always seem to be.
I'm assuming this is just my misunderstanding of the way threading works, so hopefully someone can enlighten me.
© Stack Overflow or respective owner