2010-07-18 5 views
1
public Class Test{ 
    GetDataset(RandomBoolean uncertain); 
    GetDataset2(); 
    GetDataset3(); 
} 

où les définitions de méthode sonttest si une autre méthode sur un même objet a été appelé à tester la targetObject

public virtual void GetDataset2(){} 
    public virtual void GetDataset3(){} 

    public virtual void GetDataset(RandomBoolean uncertain) 
    { 
    if (uncertain.State){ 
      GetDataset2(); 
    } 
    else{ 
     GetDataset3(); 
    } 
    } 

    //mocking uncertain.State to return true 
    //ACT 
    testObject.GetDataset(uncertainMock); 

Je veux tester si GetDataset2() a été appelé en interne que je prépare sur testObject.GetDataset() ; Je ne suis pas se moquant de la testObject parce qu'il est l'objet de test, donc si je tente de faire

testObject.AssertWasCalled(x => x.GetDataset2()); 

Il ne me laisse pas faire cela parce que testObject n'est pas un objet moqué. J'utilise Rhino Mocks 3.5, il me manque définitivement quelque chose ici. Quel est le meilleur moyen d'y parvenir?

+0

Aussi je veux le faire dans AAA et pas l'ancienne syntaxe. – Usman

+0

Après avoir lu les deux réponses ci-dessous, j'ai modifié un peu le code, pour le rendre plus clair et poser une question en cascade. Ce que je comprends des réponses ci-dessous est que, dans GetDataset (int a), tout ce que je peux faire est de vérifier cela incertain.Etat a été utilisé et je ne peux pas tester si la décision prise à ce sujet était correcte ou non. Ce qui signifie que si un autre développeur échange plus tard les deux méthodes et que je n'ai aucun test unitaire vérifiant le comportement, je ne le saurai pas. – Usman

+0

J'ai posé cette question parce que j'étais sous l'hypothèse que je peux en particulier se moquer de l'objet de test lui-même et voir si ses autres méthodes sont appelées, je ne savais pas comment faire cela avec AAA en 3.5. – Usman

Répondre

3

La réponse courte est: vous ne pouvez pas. D'autre part, vous ne voulez généralement pas. Lorsque vous testez la classe à l'unité, vous voulez vous assurer que la classe effectue son calcul correctement et qu'elle a les effets secondaires corrects. Vous ne devriez pas tester les internes de la classe, car cela provoque un couplage du code réel et des tests trop forts. L'idée est que vous pouvez changer librement l'implémentation de votre classe et utiliser vos tests pour vous assurer que cela fonctionne correctement. Vous ne seriez pas en mesure de le faire si vos tests inspectent l'état interne ou le flux.

Vous avez 2 options (selon le contexte)

  1. Vous pouvez structurer vos tests d'une manière qu'ils ne regardent que l'extérieur comportement visible
  2. Si (1) est trop dure, on peut refactorisation GetDataset2 en une classe séparée. Ensuite, vous seriez en mesure de se moquer tout en testant la méthode GetDataset.
0

Ce n'est généralement pas comme cela que les tests unitaires avec des modèles fonctionnent. Vous devez vous soucier des collaborateurs (que vous talonnerez/moqueriez) et des résultats (changements d'état dans le cas des méthodes void), et non du fonctionnement interne du système testé (nonobstant les appels aux collaborateurs). C'est à la fois parce que et pourquoi vous ne pouvez pas faire ces types d'observations comportementales (du moins sans changer vos classes pour accommoder les tests, en exposant des membres privés ou en ajoutant des membres révélateurs d'état - pas de bonnes idées).

0

Il y a quelques informations sur les moqueurs partiels here. Voici quelques code snippets sur comment faire cela avec RhinoMocks et Moq.

Essayez ceci:

using Rhino.Mocks; 
public class TestTest { 
[Test] 
public void FooTest() 
{ 
    var mock = new MockRepository().PartialMock<Test>(); 
    mock.Expect(t => t.GetDataset2()); 

    mock.GetDataset((RandomBoolean)null); 

} 
} 
+0

Ce n'est pas la syntaxe AAA AFAIK. – Usman

+0

Oui, vous avez raison. Laissez-moi voir ce que la nouvelle syntaxe est. –

+0

Mis à jour à nouveau. Essayez-le. –

0

En plus d'utiliser une maquette partielle via Rhino Mocks, vous pouvez également créer classe dérivée de test qui remplace la mise en œuvre de GetDataSet2() avec une fonction qui enregistre il a été appelé. Ensuite, vérifiez cela dans votre test.

C'est une odeur de code que vous faites trop dans une classe cependant.

Questions connexes