lunes, 16 de junio de 2008

Restricciones con Rhino Mock 3.4 o Constraints en Rhino Mocks, o cómo limitar los valores de los parámetros con mock objects

Rhino Mocks Constraints o restricciones en Rhino Mocks 3.4
Otra de las características interesantes de un framework de mock es la posiblidad de poner restricciones a los valores que pueden recibir los parámetros de un objeto que estamos "moqueando", esto es, que nuestra Expectation permite definir que el método sólo pueda ser llamado con ciertos valores en sus parámetros, por ejemplo que un parámetros sea exáctamente 2 o mayor de 5 y mucho más.

Tipos de restricciones en Rhino Mocks

Básicamente tenemos cuatro clases con métodos estáticos para trabajar con restricciones:

Is : permite establecer restricciones del tipo "igual a" "mayor que"
Property: para trabajar con propiedades, por ejemplo propiedad tal debe tener tal valor
List: para las listas, se pueden poner restricciones a la cantidad de elementos, etc.
Text: para trabajar con texto, por ejemplo poner una validación basada en una expresión regular

En caso de no cumplir con una restricción para un parámetro Rhino nos lanza una bonita ExpectationViolationException, veámos un ejemplo:

[TestClass]
public class UnitTest1
{

    MockRepository _mocker;

    public MockRepository Mocker
    {
        get
        {
            if (_mocker == null)
                _mocker = new MockRepository();
            return _mocker;
        }
    }

    [TestMethod]
    [ExpectedException(typeof(ExpectationViolationException))]
    public void ViolacionDeConstraint()
    {
        IProcessor mockProcessor = Mocker.CreateMock<IProcessor>();
        
        using (Mocker.Record())
        {
            //grabamos un comportamiento que dice que se espera
            //una llamada el método Test en la cual el argumento
            //debe ser mayor a 3
            Expect.Call(mockProcessor.Test(0)).
                Return(true).
                Constraints(Is.GreaterThan(3));
        }

        using (Mocker.Playback())
        {
            //funciona porque devuelve true en caso de llamar al métod
            //con un parámetro mayor que 3
            Assert.IsTrue(mockProcessor.Test(4));
            //Lanza una ExpectationViolationException porque el parámetro
            //viola el constraint
            Assert.IsTrue(mockProcessor.Test(2));            
        }
    }
}

public interface IProcessor
{
    bool Test(int value);
}

Para terminar, los remito a la documentación para conocer todas las restricciones, saludos.