Я сейчас строю класс, используя TDD.Класс отвечает за ожидание того, чтобы конкретное окно стало активным, и затем запускает какой-то метод.
Я использую библиотеку AutoIt COM (для получения дополнительной информации об AutoIt смотрите здесь ), так какповедение, которое я хочу, на самом деле является единственным методом в AutoIt.
Код выглядит примерно так:
public class WindowMonitor
{
private readonly IAutoItX3 _autoItLib;
public WindowMonitor(IAutoItX3 autoItLib)
{
_autoItLib = autoItLib;
}
public void Run() // indefinitely
{
while(true)
{
_autoItLib.WinWaitActive("Open File", "", 0);
// Do stuff now that the window named "Open File" is finally active.
}
}
}
Как вы можете видеть, библиотека AutoIt COM реализует интерфейс, который я могуmock (с использованием NUnit и Rhino Mocks):
[TestFixture]
public class When_running_the_monitor
{
WindowMonitor subject;
IAutoItX3 mockAutoItLibrary;
AutoResetEvent continueWinWaitActive;
AutoResetEvent winWaitActiveIsCalled;
[SetUp]
public void Setup()
{
// Arrange
mockAutoItLibrary = MockRepository.GenerateStub<IAutoItX3>();
mockAutoItLib.Stub(m => m.WinWaitActive("", "", 0))
.IgnoreArguments()
.Do((Func<string, string, int, int>) ((a, b, c) =>
{
winWaitActiveIsCalled.Set();
continueWinWaitActive.WaitOne();
return 1;
}));
subject = new Subject(mockAutoItLibrary)
// Act
new Thread(new ThreadStart(subject.Run)).Start();
winWaitActiveIsCalled.WaitOne();
}
// Assert
[Test]
[Timeout(1000)]
public void should_call_winWaitActive()
{
mockAutoItLib.AssertWasCalled(m => m.WinWaitActive("Bestand selecteren", "", 0));
}
[Test]
[Timeout(1000)]
public void ensure_that_nothing_is_done_while_window_is_not_active_yet()
{
// When you do an "AssertWasCalled" for the actions when the window becomes active, put an equivalent "AssertWasNotCalled" here.
}
}
Проблема в том, что первый тест не работает.Я уже выяснил, что когда вызывается заглушка «WinWaitActive», она блокируется (как и предполагалось, в отдельном потоке), а когда после этого вызывается «AssertWasCalled», выполнение никогда не возвращается.
I 'Я в растерянности, как действовать, и я не смог найти никаких примеров макетирования блокирующего вызова.
Итак, в заключение:
Есть ли способ высмеять блокирующий вызов, не делаятайм-аут тестов?
(PS Меня меньше интересует изменение дизайна (т. е. «Не используйте блокирующий вызов»), поскольку здесь можно сделать это, но я уверен, что естьв тех случаях, когда изменить дизайн намного сложнее, и меня интересует более общее решение, но если просто невозможно высмеять блокировку вызовов, подобные предложения приветствуются!)