J'ai une méthode statique publique qui utilise un objet de classe aléatoire pour générer un entier. L'entier est alors fait l'index d'une liste. Je veux tester la logique de la méthode tout en contrôlant ce qu'est la prochaine méthode d'un objet aléatoire renvoie.
[TestClass] public class RandomGeneratorSpec { [TestMethod] public void GetRandomListMember_ListOfStrings() { List<string> strings = new List<string> { "red", "yellow", "green" }; Mock<Random> mockRandom = new Mock<Random>(); mockRandom.Setup(rand => rand.Next(strings.Count)).Returns(() => 2); // 2! string result = RandomGenerator.GetRandomListMember(strings); Assert.AreEqual("green", result); } }
3 Réponses :
Vous pouvez créer votre propre classe aléatoire code> localement avec les méthodes dont vous avez besoin pour redéfinir à partir de la classe
system.random code> classe.
class Program
{
static void Main(string[] args)
{
var rand = new Random();
int next = rand.Next(); // uses my local Random class.
}
}
class Random
{
public int Next() => 2;
}
C'était plus une réponse explicite à la question, mais j'apprends définitivement de la réponse de Nkosi ci-dessous.
envisager de refactoring pour permettre une conception plus maintenable qui permet une plus grande flexibilité avec l'utilisation et la test de la classe de sujets p> de sorte qu'elle puisse être injectée explicitement si nécessaire et ne pas être utilisé statiquement comme une dépendance étroitement couplée qui peut être considéré comme une odeur de code. p> p>
Un exemple de ma suggestion dans le commentaire:
[TestClass] public class RandomGeneratorSpec { [TestMethod] public void GetRandomListMember_ListOfStrings() { List<string> strings = new List<string> { "red", "yellow", "green" }; string result = RandomGenerator.GetRandomListMember(strings); Assert.IsTrue(strings.Contains(result)); } }
Vous ne devriez pas avoir à si vous concevez votre code de manière optimale.
MOQ fonctionne mieux avec des abstractions non statiques
Si l'objectif final est d'obtenir une liste de numéros «aléatoires» prévisibles, une alternative à la moqueur consiste à utiliser le paramètre de graines de la classe aléatoire.
Je ne vois pas vraiment le point de votre test de l'unité ici. Si vous "simulez" la classe aléatoire, tout ce que vous testez vraiment est si vous êtes capable de récupérer un élément de la liste. Un test d'unité plus sensible IMHO serait de valider que l'élément véritablement choisi au hasard est contenu dans la liste que vous fournissez dans votre test.