我正在尝试找出对此类进行单元测试的最佳方法:
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 */
}
}
它不应该是最完善的课程,只是想弄清楚一些事情!
然后我有一个单元测试,我想在其中启动然后停止服务,断言私有“进程”方法对数据库或文件系统做了一些事情。
我的单元测试如下(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 的方式,效果非常好 :)
公共接口 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()!
:)