2010-11-02 10 views
30

He una interfaz definida comoMOQ - la creación de un método basado en valores de argumento (múltiples argumentos)

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

que puede configurar un Moq básico para lo anterior de la siguiente manera:

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

llamada que

mock.Object.AddNumbersBetween(1,4); 

y luego verifique que se llama

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

me puedo imaginar cómo configurar los AddNumbersBetween método tal que si el upperVal es inferior a la lowerVal se produce una excepción

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

Esencialmente buscando algo como:

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

Recomendaría simplemente implementar la lógica de lanzamiento de excepción con una Devolución de llamada, ya que eso le da acceso completo a ambos parámetros. Hasta donde yo sé, las cláusulas de coincidencia de parámetros solo pueden realizar una lógica basada en un solo parámetro. –

Respuesta

62

Sé que este es un año de edad, pero he encontrado una manera de utilizar múltiples parámetros con la última versión del Moq al menos:

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

+1, pero tiene un error tipográfico. Necesita poner un '=>' entre '(a, b)' y '{return a NightOwl888

+1

Gracias, parece que Piotr se encargó de eso gracias. – Gustyn

+1

¡Agradable, funcionó para mí! – willem

8

Para métodos de un solo argumento, la manera más limpia sería:

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

Esto no se puede aplicar si el método tiene varios argumentos. Todavía hay una 'solución' que se podría utilizar, que imita lo que quiere lograr:

/// <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

Esto funciona solo en un solo parámetro y no en múltiples parámetros –

+0

Mi mal ... hay otra forma de manejar esto, con una devolución de llamada que lanzará la excepción si los argumentos no pasan su validación. He editado mi respuesta con ese método – srodriguez

Cuestiones relacionadas