2010-06-15 11 views
1

J'ai lu quelques-unes des discussions sur le groupe d'utilisateurs Moq et n'ont pas réussi à trouver un exemple et ont été jusqu'à présent incapable de trouver le scénario que j'ai. Voici ma question et le code:moqueur comportement de collecte avec Moq

// 6 periods 
var schedule = new List<PaymentPlanPeriod>() 
{ 
    new PaymentPlanPeriod(1000m, args.MinDate.ToString()), 
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(1).ToString()), 
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(2).ToString()), 
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(3).ToString()), 
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(4).ToString()), 
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(5).ToString()) 
}; 

// Now the proxy is correct with the schedule 
helper.Setup(h => h.GetPlanPeriods(It.IsAny<String>(), schedule)); 

Puis dans mes tests, j'utiliser des périodes mais le Raillé _PaymentPlanHelper jamais Remplit la collection, voir ci-dessous pour l'utilisation:

public IEnumerable<PaymentPlanPeriod> Periods 
{ 
get 
{ 
    if (CanCalculateExpression()) 
    _PaymentPlanHelper.GetPlanPeriods(this.ToString(), _PaymentSchedule); 

    return _PaymentSchedule; 
} 
} 

Maintenant, si je change l'objet moquaient utiliser une autre méthode surchargée de GetPlanPeriods qui renvoie une liste comme suit:

var schedule = new List<PaymentPlanPeriod>() 
{ 
    new PaymentPlanPeriod(1000m, args.MinDate.ToString()), 
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(1).ToString()), 
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(2).ToString()), 
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(3).ToString()), 
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(4).ToString()), 
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(5).ToString()) 
}; 

helper.Setup(h => h.GetPlanPeriods(It.IsAny<String>())).Returns(new List<PaymentPlanPeriod>(schedule)); 

List<PaymentPlanPeriod> result = new _PaymentPlanHelper.GetPlanPeriods(this.ToString()); 

Cela fonctionne comme prévu. Tous les pointeurs serait génial, aussi longtemps que vous ne bash pas mon architecture ... :)

Merci, Stephen

+1

Ai-je raison de dire que vous voulez que votre appel de méthode mockée modifie le paramètre de planification qui lui est passé? Cette question SO peut aider - la réponse utilise des rappels http://stackoverflow.com/questions/2183691/how-to-modify-an-invocation-parameter-of-a-mocked-method-with-moq –

+0

Oui David. Je lis l'autre poste en ce moment. Je vous remercie. –

Répondre

4

La configuration méthode consiste essentiellement à configurer un comportement expeced. Par exemple, pour configurer une instance Mock pour renvoyer certaines valeurs. Par exemple, une configuration maquette:

var configMock = new Mock<IConfiguration>(); 
configMock.Setup(c=>c.GetSetting("Title")).Returns("Hello Word"); 
configMock.Setup(c=>c.GetSetting("Answer")).Returns("42"); 

Cela signifie que lorsque vous passez « Titre » à la GetSetting méthode la maquette sera de retour « Bonjour mot ». Et quand vous passez "Réponse" à la maquette, elle renverra "42". De plus, vous pouvez configurer des caractères génériques. Par exemple:

var configMock = new Mock<IConfiguration>(); 
configMock.Setup(c=>c.GetSetting(It.IsAny<String>())).Returns("Hello Word"); 

Maintenant, la maquette sera de retour pour tout appel à la GetSetting méthode la chaîne « Bonjour tout le monde »

Maintenant, dans votre premier cas, vous configurez la maquette de cette façon: Attendez-vous à un appel GetPlanPeriods avec n'importe quelle chaîne et cette liste. Donc, avec le deuxième paramètre, vous spécifiez quelle liste vous attendez. Mais vous ne configurez aucun bahvior pour cet appel.

Afaik vous pouvez configurer Moq à quelque chose avec les arguments. Comme ceci:

helper.Setup(c => c.GetPlanPeriods(It.IsAny<string>(),It.IsAny<List<PaymentPlanPeriod>>())) 
      .Callback((string s, List<PaymentPlanPeriod> l)=> 
          { 
           l.Add(new PaymentPlanPeriod(1000m, args.MinDate.ToString())); 
          }); 

Dans le second exemple, vous configurez la maquette de cette façon: Attendez-vous un appel à GetPlanPeriods avec une chaîne et retourne cette liste. Donc, il reviendra pour tout appel de la liste donnée. Thats pourquoi cela fonctionne.

Je généralise Je recommanderais de concevoir votre API de telle sorte que vous soyez le deuxième exemple. Préférez retourner la collection modifiée au lieu de mettre à jour la collection transmise. Utiliser et se moquer de telles méthodes est beaucoup plus facile.