2008-10-08 6 views
1

J'ai une classe qui est conçue pour faire tourner un thread d'arrière-plan, à partir de laquelle les appels seront transformés en gestionnaire. Ce gestionnaire sera raillé aux fins du test unitaire. Le fragment correspondant du code est:Comment définir les attentes pour les appels qui seront effectués sur un autre thread dans Rhino Mocks

MockRepository mocks = new MockRepository(); 
ICacheManager manager = mocks.CreateMock<ICacheManager>(); 

Expect.On(manager).Call(manager.CacheSize).Return(100); 
mocks.ReplayAll(); 

CacheJanitor janitor = new CacheJanitor(manager); 

// get janitor to do its stuff 
// ... 

mocks.VerifyAll(); 

Le problème est que lors de la vérification, nous obtenons deux exceptions lancées - l'un sur le fil d'essai indiquant qu'un appel à CacheSize était attendu mais n'a pas eu lieu, et un autre sur l'arrière-plan thread (dans CacheJanitor) indiquant qu'un appel à CacheSize s'est produit mais n'était pas prévu.

De toute évidence, les attentes ont une affinité avec le thread sur lequel elles sont créées. Est-ce que quelqu'un sait d'une façon d'instruire Rhino Mocks d'attendre l'appel sur un thread différent (qui n'existe même pas au moment où les attentes sont définies)?

EDIT:

oublié de mentionner la contrainte que nous sommes encore sur VS 2005 pour l'avenir immédiat. La version de Rhino Mocks est 3.4 - J'essaierai avec 3.5, mais la liste des améliorations ne semble pas indiquer de corrections dans ce domaine. Pour le moment je vais probablement créer mon propre objet mocké pour cette série de tests et enregistrer les résultats à l'intérieur, mais j'apprécierais certainement toutes les solutions qui me permettent d'y parvenir proprement en utilisant Rhino Mocks.

Répondre

1

Wow. C'est fou. J'ai utilisé MoQ pour faire ce genre de chose sans problème.

Quelle version de Rhino utilisez-vous? Vous l'utilisez de la manière pré-3.5; peut-être que ce ne serait pas un problème avec la version 3.5? Une autre alternative est d'éviter de vérifier les attentes sur les faux-semblants. (désolé, je ne connais pas la syntaxe de Rhino mais c'est peut-être possible). Utilisez un rappel pour définir une variable locale dans la fonction de test et vérifier sur cette variable.

En moq, je le ferais comme ceci:

// Arrange 
var called = false; 
var mock = new Mock<SomeObject>();    

mock.Expect(x => SomeFunction()).Callback(() => called = true);    

var target = new MultithreadedTarget(mock.Object);    

// Act 
target.DoSomethingThatCallsSomeFunctionOnAnotherThreadLol();    

// this part is a bit ugly 
// spinlock for a bit to give the other thread a chance 
var timeout = 0; 
while(!called && timeout++ < 1000) 
    Thread.Sleep(1); 

// Assert 
Assert.IsTrue(called); 
+0

Malheureusement, ce que la moitié travaille avec RM. Je reçois toujours la violation d'attente sur le fil de fond, parce que je n'ai aucun moyen de dire à RM d'attendre ou de l'ignorer. Cette exception est évidemment levée lorsque la propriété mockée est accédée, pas lorsque VerifyAll est appelée. –

Questions connexes