Я пытаюсь найти лучший способ для юнит-тестирования этого класса:
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 ()!
:)