Utiliser Moq pour définir les indexeurs en C#

j'ai du mal à trouver comment mettre indexeurs en C# avec Moq. La documentation du Moq est faible, et j'ai fait beaucoup de recherches... ce que j'aimerais faire est similaire dans la solution à comment définir un Moq:

var someClass = new Mock<ISomeClass>();
someClass.SetupSet(o => o.SomeIndexedProperty[3] = 25);

je veux modifier la ci-dessus pour travailler pour tout index et de toute valeur, de sorte que je peux faire quelque chose comme ceci:

someClass.Object.SomeIndexedProperty[1] = 5;

actuellement j'ai ce qui suit, qui fonctionne très bien pour la propriété indexée fonceur, mais si jamais je définissez la valeur Moq l'ignore:

var someValues = new int[] { 10, 20, 30, 40 };
var someClass = new Mock<ISomeClass>();
someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()])
    .Returns<int>(index => someValues[index]);

// Moq doesn't set the value below, so the Assert fails!
someClass.Object.SomeIndexedProperty[3] = 25;
Assert.AreEqual(25, someClass.Object.SomeIndexedProperty[3]);
19
demandé sur Community 2010-05-27 00:04:59

3 réponses

j'ai trouvé une solution à mon problème. Il exige un changement dans ma façon de penser... J'avais été à la recherche d'utiliser NUnit Assert pour vérifier que l'indexeur setter dans mon someClass mock était appelé avec la bonne valeur.

il semble qu'avec Moq la façon de faire est d'utiliser le VerifySet fonction. Un exemple artificiel:

someClass.Object.SomeIndexedProperty[3] = 25;
someClass.VerifySet(mock => mock.SomeIndexedProperty[3] = 25);

le test de l'unité est réussi depuis SomeIndexedProperty[3] est fixé à 25, mais non autrement.

11
répondu M. Dudley 2010-05-27 13:51:51

Utilisant Moq 3.1.416.3

Setup ne fonctionnera pas pour les indexeurs (parce qu'il faut une expression qui signifie que les instructions d'affectation sont exclues)

vous devez donc utiliser SetupSet comme

_settingsStore.SetupSet(store => store["MruNotes"] = It.IsAny<string>())
                .Callback<string,string>( (key, value) => persistedValue = value);

Une petite mise en garde: cette expression ne correspond que si la clé est "MruNotes". Je n'ai pas pu utiliser une allumette comme ça.IsAny pour la clé.

5
répondu Gishu 2010-11-27 18:47:38

dans votre test vos seules attentes définies pour le getter de l'indexeur - et cela retournera toujours la valeur correspondante de votre tableau. L'indexeur ne se comporte pas comme une chose réelle. Vous pouvez essayer quelques choses pour avoir fixé:

  1. vous pouvez vérifier si vous pouvez couper cet indexeur. J'utilise personnellement RhinoMocks, donc je n'ai aucune idée si cela est implémenté

    someClass.SetupProperty(f => f.SomeIndexedProperty);
    
  2. vous pouvez essayer de moquer le setter aussi bien et le faire pour changer le sous-jacent tableau. Ma première hypothèse serait d'essayer quelque chose dans ce sens (pas de garantie que cela fonctionne):

    someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()] = It.IsAny<int>())
    .Callback((index, value) => someValues[index] = value);
    
  3. ou si L'interface ISomeClass est assez petite, vous pouvez créer vous-même une implémentation stub (qui aurait l'indexeur implémenté comme un dictionnaire, un tableau, etc.)

3
répondu Grzenio 2015-03-25 15:20:45