このクラスを単体テストするための最良の方法を見つけようとしています:
public class FileGroupGarbageCollector
{
private Task _task;
private readonly AutoResetEvent _event = new AutoResetEvent(false);
public void Start()
{
_task = Task.Factory.StartNew(StartCollecting);
}
public void Stop()
{
_event.Set();
}
private void StartCollecting()
{
do
{
Process();
}
while (!_event.WaitOne(60000, false));
}
private void Process()
{
/* do some work to the database and file system */
}
}
何かを理解しようとしているだけなので、最も適切に形成されたクラスである必要はありません。
次に、プライベート 'Processs' メソッドがデータベースまたはファイルシステムに何かをしたことをアサートして、サービスを開始してから停止する単体テストを行います。
私の単体テストは次のとおりです(nunit):
[Test]
public void TestStart()
{
var fg = new FileGroupGarbageCollector(30000);
fg.Start();
Thread.Sleep(5000); // i hate this!
fg.Stop();
// assert it did what i wanted it to do!
}
Thread.Sleep() を回避できるように、ここで使用できる方法や素敵なパターンはありますか? 単体テストで眠るという考えは嫌いですが (プロダクション コードは言うまでもなく)、プライベートな機能をテストすることは拒否します! このクラスのパブリック インターフェイスをテストしたいと思います。
どんな答えでも大歓迎です:)
回答後に更新
私はIoCの方法を採用しましたが、それは本当にうまく機能します:)
public interface IEventFactory { IEvent Create(); }
public interface IEvent
{
bool WaitOne(int timeout);
void Set();
}
次に、私のモック オブジェクト (Moq を使用):
var mockEvent = new Mock<IEvent>();
var mockEventFactory = new Mock<IEventFactory>();
mockEvent.Setup(x => x.WaitOne(It.IsAny<int>())).Returns(true);
mockEvent.Setup(x => x.Set());
mockEventFactory.Setup(x => x.Create()).Returns(mockEvent.Object);
IEvent.WaitOne() を呼び出すとすぐに true が返されて終了するため、Thread.Sleep() は必要ありません。
:)