Мы разрабатываем приложение WPF с использованием TDD. Поскольку мы уже работаем над этим решением в течение почти двух лет, мы написали огромное количество тестов (сейчас почти 2000 юнит-тестов).
Есть несколько классов, которые должны реализовывать многопоточные и асинхронные функции. Например, коммуникационный компонент, который может отправлять и получать сообщения и анализировать их. Зависимости всегда проверяются с помощью RhinoMocks.
Наши тестовые методы, предназначенные для этих классов, выглядят очень похоже, как показано ниже:
[TestMethod]
public void Method_Description_ExpectedResult(){
// Arrange
var myStub = MockRepository.GenerateStub<IMyStub>();
var target = new MyAsynchronousClass(myStub);
// Act
var target.Send("Foo");
Thread.Sleep(200);
//Assert
myStub.AssertWasCalled(x => x.Bar("Foo"));
}
Как видите, этот тест выполняется не менее 200 мс из-за Thread.Sleep (). Мы оптимизировали тест, заменив AssertWasCalled активным методом опроса, s.th. как это:
public static bool True(Func<bool> condition, int times, int waitTime)
{
for (var i = 0; i < times; i++)
{
if (condition())
return true;
Thread.Sleep(waitTime);
}
return condition();
}
Теперь мы можем использовать этот метод WaitFor.True (...), изменив AssertWasCalled на:
var fooTriggered = false;
myStub.Stub(x => x.Bar("Foo")).Do((Action)(() => fooTriggered = true)));
WaitFor.True(() => fooTriggered, 20, 20);
Assert.IsTrue(fooTriggered);
Эта конструкция завершится раньше, если условие будет соответствовать, но в любом случае - это займет слишком много времени для нас. На выполнение всех наших 2000 тестов требуется около 5 минут (сборка и запуск).
Есть ли хитрый трюк, как мы могли бы оптимизировать код, подобный этому?