2017-05-19 1 views
0

Je suis nouveau à moquer C#, j'essaie de lire du code et j'ai échoué l'un des tests, pouvez-vous s'il vous plaît m'expliquer ce que le code source ci-dessous essaie de tester et quand ça échoue?C# moqueuse Mock <StreamWriter>

Mock<StreamWriter> _streamWriterMock; 
string[] expectedLines; 
. 
. 
. 
foreach (var line in expectedLines) 
{ 
    _streamWriterMock.Verify(a => a.Write(line), Times.Exactly(1)); 
} 
+1

Ce n'est pas un [mcve]. Le code omis fait qu'il est difficile de dire ce qu'il est testé ainsi que l'omission du sujet à tester. Au mieux, 'foreach' vérifie avec le simulacre que les lignes attendues ont été appelées sur la méthode Write de l'auteur du flux. – Nkosi

+0

Quel cadre de moquerie utilisez-vous? –

Répondre

2

Vérifier
Vous pouvez vérifier que la méthode à l'essai a été appelé, ou même combien de fois cette méthode a été appelée

Juste pour reproduire le problème essayez ce code

class Program 
{ 
    static void Main(string[] args) 
    { 
     var _streamWriterMock = new Mock<StreamWriter>("output.txt"); 
     string[] expectedLines= new []{"test","test"}; 

     foreach (var expectedLine in expectedLines) 
     { 
      _streamWriterMock.Object.Write(expectedLine); 
     } 
     foreach (var line in expectedLines) 
     { 
      _streamWriterMock.Verify(a=>a.Write(line),Times.Exactly(1));  
     } 

    } 
} 

En fait, si vous essayez de railler votre code avec le tableau {"test","test"}, vous obtiendrez une exception
Expected invocation on the mock exactly 1 times, but was 2 times: a => a.Write("test")

Mais si votre tableau est quelque chose comme

string[] expectedLines= new []{"test","test1"};

Votre maquette sera exécutée correctement

Ainsi, votre verify vérifiera si votre méthode est appelée une seule fois pour la même entrée. Je pense que l'objectif principal du code est d'omettre que vous écrivez deux fois la même sortie.

0

Le test dans votre exemple itère à travers toutes les chaînes dans votre tableau expectedLines et vérifie que _streamWriterMock.Write (valeur de chaîne) est appelée sur chacun d'eux exactement une fois. Il échouera si Write n'est pas appelé ou est appelé plusieurs fois sur l'une des chaînes.

Mise à jour

méthodes Généralement moquaient doivent être cadre virtuel et en fonction de votre moquerie, la méthode de la maquette peut avoir besoin d'être mis en place avant d'être appelé donc il ne peut pas être un test valable du tout depuis StreamWriter est un béton class et Write n'est pas une méthode virtuelle.

0

Compte tenu de la moquée StreamWriter

Au mieux la boucle foreach utilisée pour vérifier avec la maquette que la chaque chaîne dans le tableau lignes prévu a été appelé la méthode de l'auteur de flux moqué Write exactement une fois au cours de l'exercice du sujet sous test.

Le test échouera si l'une des lignes attendues est écrite plusieurs fois.

Revue Moq: Quickstart - Verification

Prenez la classe suivante comme exemple d'un sujet possible qui dépend d'une StreamWriter

public class SubjectUnderTest { 
    private StringWriter stringWriter; 

    public SubjectUnderTest(StringWriter stringWriter) { 
     this.stringWriter = stringWriter; 
    } 

    public void WriteLines(string[] lines) { 
     foreach (var line in lines) { 
      this.stringWriter.Write(line); 
     } 
    } 
} 

La dépendance serait moqué lors du test et la fonctionnalité de la méthode en cours de test peut être vérifié de manière isolée.

Par exemple.

[TestMethod] 
public void TestMethod1() { 
    //Arrange 
    var _streamWriterMock = new Mock<StringWriter>(); 
    string[] expectedLines = new[] { "line1", "line2" }; 
    var subject = new SubjectUnderTest(_streamWriterMock.Object); 

    //Act 
    subject.WriteLines(expectedLines); 

    //Assert 
    foreach (var line in expectedLines) { 
     _streamWriterMock.Verify(a => a.Write(line), Times.Exactly(1)); 
    } 
} 

Si toutefois, expectedLines avait des doublons comme { "lineN", "lineN" } Ensuite, le test ci-dessus échoueraient que la vérification attend la méthode Write être appelée exactement un temps avec une valeur de chaîne donnée.