В настоящее время я создаю класс с использованием 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 реализует интерфейс, который я могу имитировать (используя 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», выполнение никогда не возвращается.
Я не понимаю, как действовать дальше, и я не смог найти ни одного примера имитации блокирующего вызова.
Итак, в заключение:
Есть ли способ имитировать блокирующий вызов без тайм-аута тестов?
(PS Меня меньше интересует изменение дизайна (например, «Не использовать блокирующий вызов»), так как это может быть возможно здесь, но я уверен, что есть случаи, когда намного сложнее изменить дизайн , и меня интересует более общее решение. Но если имитировать блокирующие вызовы просто невозможно, подобные предложения приветствуются!)