2009-01-21 7 views
2

Commençons avec Rhino Mocks et j'ai un problème très simple, comment puis-je simuler une classe avec un vide qui définit une propriété?Rhino Mocks, void et propriétés

class SomeClass : ISomeClass 
{ 
    private bool _someArg; 

    public bool SomeProp { get; set; } 

    public SomeClass(bool someArg) 
    { 
     _someArg = someArg; 
    } 

    public void SomeMethod() 
    { 
     //do some file,wcf, db operation here with _someArg 
     SomeProp = true/false; 
    } 
} 

De toute évidence, il s'agit d'un exemple très artificiel, Merci.

Répondre

6

Dans votre exemple, vous ne aurez pas besoin RhinoMocks parce que vous êtes apparemment tester la fonctionnalité de la classe sous test. tests unitaires simple fera à la place:

[Test] 
public void SomeTest() 
{ 
    var sc = new SomeClass(); 
     // Instantiate SomeClass as sc object 
    sc.SomeMethod(); 
     // Call SomeMethod in the sc object. 

    Assert.That(sc.SomeProp, Is.True); 
     // Assert that the property is true... 
     // or change to Is.False if that's what you're after... 
} 

Il est beaucoup plus intéressant de tester se moque quand vous avez une classe qui a des dépendances sur d'autres classes. Dans votre exemple, vous mentionnez:

// Code fichier, WCF, opération db ici avec _someArg

à savoir vous vous attendez à ce que d'autres classes définissent la propriété de SomeClass, ce qui a plus de sens pour mocktest. Exemple:

public class MyClass { 

    ISomeClass _sc; 

    public MyClass(ISomeClass sc) { 
     _sc = sc; 
    } 

    public MyMethod() { 
     sc.SomeProp = true; 
    } 

} 

Le test requis irait quelque chose comme ceci:

[Test] 
public void MyMethod_ShouldSetSomeClassPropToTrue() 
{ 
    MockRepository mocks = new MockRepository(); 
    ISomeClass someClass = mocks.StrictMock<ISomeClass>(); 

    MyClass classUnderTest = new MyClass(someClass); 

    someClass.SomeProp = true; 
    LastCall.IgnoreArguments(); 
     // Expect the property be set with true. 

    mocks.ReplayAll(); 

    classUndertest.MyMethod(); 
     // Run the method under test. 

    mocks.VerifyAll(); 
} 
+0

Dans votre dernier exemple, le Lastcall.IgnoreArguments(); serait une fausse passe parce que vous pourriez aussi passer le test en passant someClass.SomeProp = false; – mendicant

3

Dépend de la fidélité que vous souhaitez dans votre objet maquette. Le moyen facile de le faire est de ne pas s'inquiéter à ce sujet et d'écrire des déclarations inattendues stupides.

[Test] 
public void SomeTest() 
{ 
    MockRepository mocks = new MockRepository(); 
    ISomeClass mockSomeClass = mocks.StrictMock<ISomeClass>(); 
    using(mocks.Record()) 
    { 
     using(mocks.Ordered()) 
     { 
     Expect.Call(MockSomeClass.SomeProp).Return(false); 
     Expect.Call(delegate{MockSomeClass.SomeMethod();}); 
     Expect.Call(MockSomeClass.SomeProp).Return(true); 
     } 
    } 
} 

Si vous voulez quelque chose qui agit plus comme l'objet réel sans un ensemble de réponses en conserve ordonné que vous aurez à mettre en place des délégués à la méthode de faire sur l'attendre.

delegate bool propDelegate(); 
delegate void methodDelegate(); 
private bool m_MockPropValue = false; 

[Test] 
public void SomeTest() 
{ 
    MockRepository mocks = new MockRepository(); 
    ISomeClass mockSomeClass = mocks.StrictMock<ISomeClass>(); 
    using(mocks.Record()) 
    { 
     SetupResult.For(MockSomeClass.SomeProp).Do(new propDelegate(delegate 
     { 
     return this.m_MockPropValue; 
     })); 
     Expect.Call(delegate{MockSomeClass.SomeMethod();}).Do(new methodDelegate(delegate 
     { 
     this.m_MockPropValue = true; 
     })); 
    } 
} 
+0

Et comment puis-je affirmer que SomeMethod a été appelé? –

+0

En utilisant Expect.Call (s => s.SomeMethod()) –

+0

Expansion sur le commentaire de Slace, Suite au bloc using (mocks.Record()) vous auriez un bloc using (mocks.Playback()). Lorsque vous quittez le bloc de lecture, toute attente que vous avez définie dans le bloc d'enregistrement qui n'a pas été satisfaite entraîne un test échoué. –

0

Lorsque votre préparation avec quelque chose soit SetupResult.For ou Expect.Call vous devez vous assurer qu'ils sont virtuel, sinon RhinoMocks sera incapable de faire sa propre mise en œuvre.

Sinon, il est juste une question de la définition des résultats et de faire des appels attendus Pedersen Scott a montré

0

Il est pas tout à fait claire de la question ce que l'objet que vous essayez de test est - si vous voulez simplement pour vérifier que SomeClass.SomeMethod() définit une propriété alors vous n'avez pas besoin moqueuse puisque vous pouvez juste faire un simple test basé sur l'état:

[TestMethod] 
public void SomeMethodTest() 
{ 
    SomeClass s = new SomeClass(); 
    s.SomeMethod(); 

    Assert.AreEqual(expectedValue, s.SomeProp); 
} 

par ailleurs, si SomeClass est une dépendance pour une autre classe, et vous voulez tester l'interaction entre cette classe et SomeClass, alors vous t l'attente de l'appel de méthode au cours de la section « Record » du test en utilisant RhinoMock, comme ceci:

[TestMethod] 
    public void CheckInteractionWithSomeClass() 
    { 
     MockRepository mocks = new MockRepository(); 
     ISomeClass someClass = mocks.StrictMock<ISomeClass>(); 

     using (mocks.Record()) 
     { 
      //record expection that someClass.SomeMethod will be called... 
      someClass.SomeMethod(); 
     } 

     using (mocks.Playback()) 
     { 
      //setup class under test - ISomeClass is injected through the constructor here... 
      ClassUnderTest o = new ClassUnderTest(someClass); 

      o.MethodOnClassUnderTestThatShouldCallSomeClass.SomeMethod(); 

      //any other assertions... 
     } 
    } 
Questions connexes