ada*_*iko 5 multithreading nunit unit-testing sleep thread-sleep
我正在试图找出对这个类进行单元测试的最佳方法:
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 */
}
}
Run Code Online (Sandbox Code Playgroud)
它不应该是最完美的课程,只是想弄清楚什么!
然后我有一个单元测试,我想要启动然后停止服务,断言私有'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!
}
Run Code Online (Sandbox Code Playgroud)
有什么方法或任何好的模式可以在这里使用,所以我可以避免Thread.Sleep()?我讨厌睡在单元测试中的想法(更不用说在生产代码中),但我拒绝只测试私有功能!我想测试这个类的公共接口.
任何答案都非常感谢:)
回答后更新
我采用了IoC的方式,它的工作非常好:)
public interface IEventFactory {IEvent Create(); }
public interface IEvent
{
bool WaitOne(int timeout);
void Set();
}
Run Code Online (Sandbox Code Playgroud)
然后我的模拟对象(使用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);
Run Code Online (Sandbox Code Playgroud)
因此,立即调用IEvent.WaitOne()会返回true并退出,因此不需要Thread.Sleep()!
:)
基本上,您必须在此处应用反转控制模式.因为代码是高度耦合的,所以测试它时遇到问题.
您应该明确区分所有实体并将它们放在相应的接口上.如果通过接口使用实体,则很容易模拟它.
public interface ITaskFactory {}
public interface IThreadManager {}
public interface ICollectorDatabase {}
public interface IEventFactory {}
public class FileGroupGarbageCollector
{
ITaskFactory taskFactory;
IThreadManager threadManager;
ICollectorDatabase database;
IEventFactory events;
FileGroupGarbageCollector (ITaskFactory taskFactory,
IThreadManager threadManager, ICollectorDatabase database,
IEventFactory events)
{
// init members..
}
}
Run Code Online (Sandbox Code Playgroud)
一旦所有依赖项被隔离,FileGroupGarbageCollector就不会直接使用它们中的任何一个.在您的测试中,IEventFactory mock将返回Event,如果调用WaitOne方法则不会执行任何操作.因此,您的代码中不需要任何睡眠.
尽可能多地去寻找 - 模拟,控制反转,依赖注入模式.
| 归档时间: |
|
| 查看次数: |
3428 次 |
| 最近记录: |