Je suis en train de construire une classe utilisant TDD. La classe est responsable d'attendre qu'une fenêtre spécifique devienne active, puis de déclencher une méthode.Se moquant d'un appel bloquant avec Rhino Mocks
J'utilise la bibliothèque AutoIt COM (pour plus d'informations sur AutoIt look here) puisque le comportement que je veux est en fait une seule méthode dans AutoIt.
Le code est à peu près comme suit:
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.
}
}
}
Comme vous pouvez le voir la bibliothèque AutoIt COM implémente une Wich d'interface que je peux railler (avec NUnit et 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.
}
}
Le problème est que le premier test empêche l'expiration du délai. J'ai déjà découvert que lorsque le stub "WinWaitActive" est appelé, il bloque (comme prévu, sur le thread séparé), et quand le "AssertWasCalled" est appelé après cela, l'exécution ne retourne jamais. Je ne sais pas comment procéder, et je n'ai trouvé aucun exemple de simulation d'un appel bloquant.
En conclusion:
est-il un moyen de se moquer d'un appel de blocage sans le délai d'attente des tests?
(PS Je m'intéresse moins à changer le design (c'est-à-dire "Ne pas utiliser un appel bloquant") car il est possible de le faire ici, mais je suis sûr qu'il y a des cas pour changer le design, et je suis intéressé par la solution plus générale.Mais s'il est simplement impossible de se moquer des appels bloquants, des suggestions comme celle-là sont plus que bienvenue!)
Que voulez-vous réellement tester? Pourquoi le simulacre doit-il bloquer? Pourquoi le multi-threading est-il nécessaire dans le test? –