2009 Advent Calendar December 18th

Yet another passing test to make sure our MutexLock works as expected:

    1:      public class Given_a_locked_MutexLock : IDisposable
   2:      {
   3:          private MutexLock _lock = new MutexLock();
   4:          private Thread _thread;
   5:          private bool _gotLock = false;
   6:   
   7:          public Given_a_locked_MutexLock()
   8:          {
   9:              _thread = new Thread(() =>
  10:              {
  11:                  _lock.Lock();
  12:                  _gotLock = true;
  13:                  _lock.Unlock();
  14:              });
  15:          }
  16:   
  17:          public void Dispose()
  18:          {
  19:              if (_thread != null)
  20:              {
  21:                  _thread.Abort();
  22:              }
  23:          }
  24:   
  25:          private void TakeLockAndStartThread()
  26:          {
  27:              _lock.Lock();
  28:              _thread.Start();
  29:          }
  30:   
  31:          [Fact(Timeout = 1000)]
  32:          void It_should_not_take_the_lock()
  33:          {
  34:              TakeLockAndStartThread();
  35:              Assert.False(_thread.Join(250));
  36:              Assert.False(_gotLock);
  37:          }
  38:   
  39:          [Fact(Timeout = 1000)]
  40:          void It_should_take_lock_when_released()
  41:          {
  42:              TakeLockAndStartThread();
  43:              Assert.False(_thread.Join(250));
  44:              _lock.Unlock();
  45:              Assert.True(_thread.Join(500));
  46:              Assert.True(_gotLock);
  47:          }
  48:      }

Note that I moved taking the lock from the constructor to a common helper method. This has to do with how xUnit.net runner creates objects and runs tests together with a timeout. Turns out that the object is created in one thread and then the test method is run in a separate thread if a timeout is used. In theory, if everything works as expected I don't really need the timeout but it is very nice to have it just in case the code doesn't work as expected.