Adding virtual methods to handle locks as we did yesterday is really not a good solution. The lock should be a separate object and in order to be able to fake the lock I'll make it an interface:

1: public interface Lock 2: { 3: void Lock(); 4: void Unlock(); 5: } 6:   7: public class MutexLock : Lock 8: { 9: private readonly Mutex _lock = new Mutex(); 10:   11: public void Lock() 12: { 13: _lock.WaitOne(); 14: } 15:   16: public void Unlock() 17: { 18: _lock.ReleaseMutex(); 19: } 20: }

Considering that it would be pretty neat to inject the lock dependency to the important object using generics:

1: public class ImportantObject<Tlock> where Tlock : Lock,new() 2: { 3: private readonly Tlock _lock = new Tlock(); 4:   5: public void ImportantMethod() 6: { 7: _lock.Lock(); 8: // Do things. 9: _lock.Unlock(); 10: } 11: }

Then thread safety can be tested like this:

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

However since generics are used we need a static spy in the faked lock which might be a problem if several tests run concurrently. Not typical for unit test runners but not impossible. We'll have to address that later.