如果你不想測試線程真正睡眠的事實,更直接的方法(和可能的方法)是有一個ISleepService。然後,您可以將它嘲笑出來,然後不會在測試中入睡,但是會有一個確實會導致生產代碼中出現Thread.Sleep的實現。
ISleepService sleepService = Container.Resolve<ISleepService>();
..
while (running)
{
...
// Work
...
sleepService.Sleep(Interval);
}
示例使用起訂量:
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;
}
}
}
更新
在設計\保養的注意,如果它是痛苦的改變 「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;
}
}
}
實際上改變時鐘值(我確信你不想這樣做)的缺點,你不會能夠獲得你正在尋找的結果。 – 2010-08-03 15:59:20
首選的解決方案是將定時功能與服務隔離,以便您可以嘲笑服務以進行測試。如果你不能這樣做(通常是因爲它是現有的代碼庫),那麼另一種方法是使用像Moles這樣的框架繞開靜態調用:http://research.microsoft.com/en-us/projects/moles/ – 2010-08-03 16:04:19