Share via


2009 Advent Calendar December 1st

One way of adding tests for thread safety is to let the important object handle the locking through two protected members:

    1:      public class ImportantObject
   2:      {
   3:          private Mutex _lock = new Mutex();
   4:   
   5:          public void ImportantMethod()
   6:          {
   7:              Lock();
   8:              // Do things.
   9:              Unlock();
  10:          }
  11:   
  12:          protected virtual void Lock()
  13:          {
  14:              _lock.WaitOne();
  15:          }
  16:   
  17:          protected virtual void Unlock()
  18:          {
  19:              _lock.ReleaseMutex();
  20:          }
  21:      }

Now we can write a specification that looks like this:

    1:      public class Given_an_ImportantObject
   2:      {
   3:          class TestableImportantObject : ImportantObject
   4:          {
   5:              public int NumberOfLocks { get; private set; }
   6:              
   7:              public TestableImportantObject()
   8:              {
   9:                  NumberOfLocks = 0;
  10:              }
  11:   
  12:              protected override void Lock()
  13:              {
  14:                  ++NumberOfLocks;
  15:              }
  16:   
  17:              protected override void Unlock()
  18:              {
  19:                  
  20:              }
  21:          }
  22:   
  23:          private TestableImportantObject _importantObject = new TestableImportantObject();
  24:   
  25:          [Fact]
  26:          void It_should_take_lock_when_ImportantMethod_is_called()
  27:          {
  28:              _importantObject.ImportantMethod();
  29:              Assert.Equal(1, _importantObject.NumberOfLocks);
  30:          }
  31:      }

Now we have a test/specification for thread safety! or do we?