私はマルチスレッドアプリケーションで作業していますが、同時に1つのスレッドだけが実行するコードの一部があります。複雑ではありません。私はそれを同期するためにロックを使用します。それは人生システムで働いていますが、私は、ただ1つのスレッドがクリティカルセクションにあるかどうかをチェックする単体テストを書いています。私は1つ書いたが、それは動作していたが停止します:) 私は正しい方法でテストを書く方法を把握することはできません。 NSubstituteを使ってモックを作成します。試験にスレッド同期のユニットテスト(ロック)
クラス:
public interface IMultiThreadClass
{
void Go();
}
public class Lock02 : IMultiThreadClass
{
private readonly IProcessor _processor;
private readonly string _threadName;
private static readonly object Locker = new Object();
public Lock02(IProcessor processor, string threadName)
{
_processor = processor;
_threadName = threadName;
}
public void Go()
{
//critical section
lock (Locker)
{
_processor.Process(_threadName);
}
}
}
試験:
[TestMethod()]
public void Run_Test()
{
//Only one thread should run Processor.Process, but we allow max 2 threads to catch locking erorrs
SemaphoreSlim semaphore = new SemaphoreSlim(1, 2);
//Semaphore to synchronize asserts
SemaphoreSlim synchroSemaphore = new SemaphoreSlim(0, 1);
IProcessor procesor = Substitute.For<IProcessor>();
procesor.When(x => x.Process(Arg.Any<string>())).Do(y =>
{
//increment counter to check if method was called
Interlocked.Increment(ref _counter);
//release synchro semaphore
synchroSemaphore.Release();
//stop thread and wait for release
semaphore.Wait();
});
Lock02 locker1 = new Lock02(procesor, "1");
Lock02 locker2 = new Lock02(procesor, "2");
Lock02 locker3 = new Lock02(procesor, "3");
Task.Run(() => locker1.Go());
Task.Run(() => locker2.Go());
Task.Run(() => locker3.Go());
//ASSERT
//Thread.Sleep(1000);
synchroSemaphore.Wait();
Assert.AreEqual(1, _counter);
semaphore.Release(1);
synchroSemaphore.Wait();
Assert.AreEqual(2, _counter);
semaphore.Release(1);
synchroSemaphore.Wait();
Assert.AreEqual(3, _counter);
semaphore.Release(1);
}