2010-11-02 3 views
30

I possèdent une interface définie commeMOQ - mise en place d'une méthode basée sur des valeurs d'argument (plusieurs arguments)

interface IMath 
{ 
AddNumbersBetween(int lowerVal, int upperVal); 
} 

I peut mettre en place un Moq de base de ce qui précède comme suit:

Mock<IMath> mock = new Mock<IMath>();  
mock.Setup(m => m.AddNumbersBetween(It.IsAny<int>(), It.IsAny<int>())); 

appel il

mock.Object.AddNumbersBetween(1,4); 

puis vérifiez qu'il a été appelé

mock.Verify(m => m.AddNumbersBetween(1,4), Times.AtleastOnce()); 

Je ne peux pas comprendre comment configurer la méthode AddNumbersBetween telle que si la upperVal est inférieure à la lowerVal une exception est levée

mock.Object.AddNumbersBetween(4,1);//should throw an exception 

recherche essentiellement quelque chose comme:

mock.Setup(foo => foo.AddNumbersBetween("arg1 is higher than arg2")).Throws<ArgumentException>(); 
+1

Je recommande simplement d'implémenter la logique de lancement d'exception avec un rappel, car cela vous donne un accès complet aux deux paramètres. Autant que je sache, les clauses d'appariement de paramètres ne peuvent effectuer une logique basée sur un seul paramètre. –

Répondre

62

Je sais que c'est un an, mais j'ai trouvé un moyen d'utiliser plusieurs paramètres avec la dernière version de Moq Au moins:

mock.Setup(x => x.Method(It.IsAny<int>(), It.IsAny<int>()) 
    .Returns<int, int>((a, b) => a < b); 
+0

+1, mais vous avez une faute de frappe. Vous devez mettre '=>' entre '(a, b)' et '{return a NightOwl888

+1

Merci, on dirait que Piotr s'en est occupé merci. – Gustyn

+1

Nice, a travaillé pour moi! – willem

8

Pour méthodes à un seul argument, le moyen le plus propre serait:

mock.Setup(foo => foo.Submit(IsLarge())).Throws<ArgumentException>(); 
... 
public string IsLarge() 
{ 
    return Match<string>.Create(s => !String.IsNullOrEmpty(s) && s.Length > 100); 
} 

Cela ne peut pas être appliqué si la méthode a plusieurs arguments. Il y a encore une « solution » qui pourrait être utilisé, qui imite ce que vous voulez atteindre:

/// <summary> 
/// Tests if a moq can send an exception with argument checking 
///</summary> 
[TestMethod] 
public void TestException() 
{ 
    Mock<IMath> mock = new Mock<IMath>(); 
    mock.Setup(m => m.AddNumbersBetween(It.IsAny<int>(), It.IsAny<int>())); 

    mock.Setup(foo => foo.AddNumbersBetween(It.IsAny<int>(), It.IsAny<int>())) 
     .Callback<int, int>((i, j) => CheckArgs(i, j)); 

    try 
    { 
     mock.Object.AddNumbersBetween(1, 2); 
    } 
    catch (Exception ex) 
    { 
     // Will not enter 
     Console.WriteLine("Exception raised: {0}", ex); 
    } 
    try 
    { 
     mock.Object.AddNumbersBetween(2, 1); 
    } 
    catch (Exception ex) 
    { 
     // Will enter here, exception raised 
     Console.WriteLine("Exception raised: {0}", ex); 
    } 
} 

private bool CheckArgs(int i, int j) 
{ 
    if(i > j) 
     throw new ArgumentException(); 
    return true; 
} 
+0

Cela ne fonctionne que sur un seul paramètre et pas plusieurs paramètres –

+0

Mon mauvais ... il existe une autre façon de gérer cela, avec un rappel qui lèvera l'exception si les arguments ne passent pas votre validation. J'ai édité ma réponse avec cette méthode – srodriguez

Questions connexes