2008-12-11 5 views
0

J'ai isolé le comportement dans le cas de test suivant. Je serais reconnaissant à tous ceux qui peuvent me dire comment s'attendre à/vérifier un ensemble de propriétés pour une propriété List<T> - il semble qu'il se passe quelque chose à l'intérieur It.Is<T>(predicate) qui ne me semble pas très sensé en ce moment. Exemple de code sera exécuté comme une application de console de VS2008 - vous aurez besoin d'ajouter une référence à Moq 2.6 (je suis sur 2.6.1014.1) - s'il vous plaît essayez de décommenter les différentes déclarations ExpectSet pour voir ce qui se passe ...Les tests Moq utilisant ExpectSet() avec It.Is <T>() ne se comportent pas comme ... prévu

using System; 
using Moq; 
using System.Collections.Generic; 

namespace MoqDemo { 

    public interface IView { 
     List<string> Names { get; set; } 
    } 

    public class Controller { 
     private IView view; 

     public Controller(IView view) { 
      this.view = view; 
     } 

     public void PopulateView() { 
      List<string> names = new List<string>() { "Hugh", "Pugh", "Barney McGrew" }; 
      view.Names = names; 
     } 

     public class MyApp { 
      public static void Main() { 
       Mock<IView> mockView = new Mock<IView>(); 

       // This works - and the expectation is verifiable. 
       mockView.ExpectSet(mv => mv.Names); 

       // None of the following can be verified. 
       // mockView.ExpectSet(mv => mv.Names, It.Is<Object>(o => o != null)); 
       // mockView.ExpectSet(mv => mv.Names, It.Is<List<string>>(names => names.Count == 3)); 
       // mockView.ExpectSet(mv => mv.Names, It.IsAny<IList<String>>()); 

       Controller controller = new Controller(mockView.Object); 
       controller.PopulateView(); 
       try { 
        mockView.VerifyAll(); 
        Console.WriteLine("Verified OK!"); 
       } catch (MockException ex) { 
        Console.WriteLine("Verification failed!"); 
        Console.WriteLine(ex.Message); 
       } 
       Console.ReadKey(false); 
      } 
     } 
    } 
} 

Répondre

1

Je ne suis pas en utilisant la toute dernière version de Moq, donc je n'ai pas une surcharge de ExpectSet qui prend deux paramètres, mais je l'ai eu un certain succès avec ce modèle:

mockView.ExpectSet(mv => mv.Names).Callback(n => Assert.That(n != null)); 

Le L'appel Assert (à partir de NUnit) dans le rappel lancera une exception si la valeur affectée à .Names ne correspond pas au prédicat. Cependant, il est difficile de savoir quand un test échoue. Je suis d'accord que la capacité de passer un It.Is ou It.IsAny comme deuxième paramètre serait pratique.

+0

Il n'y a pas une telle surcharge - même dans la dernière version - mais la syntaxe de rappel est exactement ce que je cherchais. Merci. –

1

Le deuxième paramètre de ExpectSet() correspond à la valeur attendue. Vous ne pouvez pas utiliser It.Is<T> dans ce cas, car il n'y a pas de surcharge qui prend un prédicat - mais ce serait bien;) Voici un extrait (simplifié) de votre échantillon, illustrant l'utilisation d'une valeur:

var mockView = new Mock<IView>(); 
var list = new List<string> { "Hugh", "Pugh", "Barney McGrew" }; 

mockView.ExpectSet(mv => mv.Names, list); 

mockView.Object.Names = list; 

Espoir qui aide.

Édition: typo fixe.

+0

D'oh. Vous avez absolument raison. Merci. –

0

Moq ne fournit pas une surcharge réception It.IsAny car il est effectivement la même chose que d'appeler ExpectSet sans passer une valeur attendue;)

1

BTW, It.Is est pas pris en charge sur ExpectSet. Votre code compile juste parce qu'ils sont des invocations de méthodes régulières lorsqu'il est utilisé comme valeurs (par opposition aux expressions), alors que lorsqu'il est utilisé dans une expression Expect ils sont pré-traités par Moq et ont une signification spécifique (plutôt que la valeur null/default tous les membres It.Is retournent effectivement).

Vous pouvez utiliser le comportement de stub sur la propriété donnée (mockView.Stub (mv => mv.Names)) et l'affirmer plus tard directement pour sa valeur après l'exécution.

Questions connexes