2010-08-17 10 views
1

Je voudrais me moquer d'une interface qui est transmise comme argument principal à une fonction, mais la méthode est compliquée, et par conséquent je ne veux pas avoir à spécifier des valeurs par défaut ou un comportement exact pour chaque test. Je voudrais spécifier des valeurs par défaut dans une méthode d'installation, et remplacer des parties spécifiques de cela dans chaque test selon les besoins.Comment puis-je configurer des actions par défaut pour une interface de simulation de rhinocéros dans une méthode de configuration, qui peut être surchargée pour un comportement spécifique dans une méthode de test?

i.e. .:

public interface IOptions 
{ 
    string Something { get; } 
} 

[TestFixture] 
public class Tester 
{ 
    MockRepository mocks; 
    IOptions someOptions; 
    string expectedXml; 

    [Setup] 
    public void Setup() 
    { 
     mocks = new MockRepository(); 
     someOptions = mocks.DynamicMock<IOptions>(); 
     //Something that would go here. 
     // I.e. SetupResult.For(someOptions.Something).Return("default"); 
    } 
    [Teardown] 
    public void Teardown() 
    { 
     mocks.ReplayAll(); 
     using (var ms = new MemoryStream()) 
     { 
      var unitUnderTest = new SomeOptionsWriter(ms); 
      unitUnderTest.Write(someOptions); 
      Assert.AreEqual(expectedXml, Encoding.Utf8.GetString(ms.ToArray())); 
     } 
     mocks.VerifyAll(); 
    } 
    [Test] 
    public void SomeTest() 
    { 
     expectedXml = "<root><default></default></root>"; 
     //Relies on default behavior 
    } 
    [Test] 
    public void SomeTest2() 
    { 
     expectedXml = "<root><sub></sub></root>"; 
     Expect.Call(someOptions.Something).Return("sub"); 
    } 
} 

Comment puis-je arriver en utilisant Rhino Mocks?

Répondre

1

Afin de répondre complètement à votre question, je dois sauter au large de la réponse de @Patrick Steele. Utilisez la configuration AAA. Déclarez vos stubs par défaut dans la méthode SetUp, puis remplacez ces stubs dans des méthodes de test spécifiques. Vous ne pourrez pas supprimer les stubs existants, sauf si vous réinstallez l'objet.

Le dernier tronçon ajouté pour une fonction donnée remplacera le précédent.

someOptions.Stub(o => o.Something).Return("default"); 
someOptions.Stub(o => o.Something).Return("override"); 

Le code ci-dessus dans l'exemple retournera "override" lorsqu'il est appelé.

+0

Comment remplace-t-on le talon? –

0

N'utilisez pas la sémantique d'enregistrement/lecture. Utilisez AAA (Arrange/Act/Assert). Dans chaque test, vous pouvez utiliser deux lignes de code pour bouchonner votre IOptions:

IOptions someOptions = MockRepository.GenerateStub<IOptions>(); 
someOptions.Stub(o => o.Something).Return("default"); 
+0

Comment ne pas * utiliser * la sémantique d'enregistrement/relecture avec Rhino Mocks? –

+0

Voir l'exemple de code ci-dessus. Je ne crée pas de référentiel Mock et je n'appelle aucune méthode "Record" ou "Replay". Je crée simplement un talon et mettre en place une fausse valeur de retour pour une propriété. Je peux maintenant passer cet objet à une méthode et cela fonctionnera. – PatrickSteele

+0

Ok. Comment chaque test individuel remplace-t-il le comportement spécifié dans le talon? –

0

Vous pouvez effacer le comportement d'un tronçon ou d'un faux comme illustré dans this other answer. Notez que cela effacera le comportement de toutes les méthodes, pas seulement une.

+0

Cela inverse le but de mettre les valeurs par défaut dans la méthode d'installation si :( –

+0

@Billy ONeal: pas si vous créez de nombreux stubs dans la méthode d'installation –

+0

Hmm .. qui suppose que la classe que je devais tester unitairement était * bien conçu *, et pas un monstre de ligne 1600 avec une monstruosité de méthode publique qui prend une classe sur laquelle 80 méthodes doivent être raillées comme paramètre :( –