gav*_*gav 11 c# multithreading unit-testing
我必须测试一个间隔后做一定工作量的方法.
while (running)
{
...
// Work
...
Thread.Sleep(Interval);
}
Run Code Online (Sandbox Code Playgroud)
Interval作为参数传递给类,所以我可以传入0或1,但我对如何模拟系统时钟感兴趣,如果不是这样的话.
在我的测试中,我希望能够通过TimeSpan Interval简单地设置时间并让线程唤醒.
我从来没有为之前对执行线程起作用的代码编写测试,我确信有一些缺陷要避免 - 请随意详细说明你使用的方法.
谢谢!
Tim*_*oyd 17
如果您不希望测试线程实际休眠的事实,那么更直接的方法(也是可能的方法)就是拥有一个ISleepService.然后你可以模拟它,然后不在你的测试中睡觉,但有一个实现确实会导致生产代码中的Thread.Sleep.
ISleepService sleepService = Container.Resolve<ISleepService>();
..
while (running)
{
...
// Work
...
sleepService.Sleep(Interval);
}
Run Code Online (Sandbox Code Playgroud)
使用Moq的示例:
public interface ISleepService
{
void Sleep(int interval);
}
[Test]
public void Test()
{
const int Interval = 1000;
Mock<ISleepService> sleepService = new Mock<ISleepService>();
sleepService.Setup(s => s.Sleep(It.IsAny<int>()));
_container.RegisterInstance(sleepService.Object);
SomeClass someClass = _container.Resolve<SomeClass>();
someClass.DoSomething(interval: Interval);
//Do some asserting.
//Optionally assert that sleep service was called
sleepService.Verify(s => s.Sleep(Interval));
}
private class SomeClass
{
private readonly ISleepService _sleepService;
public SomeClass(IUnityContainer container)
{
_sleepService = container.Resolve<ISleepService>();
}
public void DoSomething(int interval)
{
while (true)
{
_sleepService.Sleep(interval);
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新
在设计\维护说明中,如果更改"SomeClass"的构造函数是痛苦的,或者将依赖注入点添加到类的用户,那么服务定位器类型模式可以在这里提供帮助,例如:
private class SomeClass
{
private readonly ISleepService _sleepService;
public SomeClass()
{
_sleepService = ServiceLocator.Container.Resolve<ISleepService>();
}
public void DoSomething(int interval)
{
while (true)
{
_sleepService.Sleep(interval);
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11471 次 |
| 最近记录: |