2009-04-20 9 views
57

me gustaría establecer un valor de retorno¿Cómo borrar las expectativas previas en un objeto?

_stubRepository.Stub(Contains(null)).IgnoreArguments().Return(true); 

pero luego en una prueba específica, caso omiso de esa expectativa de volver falsa.

Algo así como:

_stubRepository.ClearExpectations(); //<- this does not exist, I'm just making something up 
_stubRepository.Stub(Contains(null)).IgnoreArguments().Return(false); 

Aviso, no quiero que la expectativa para volver falsa en la segunda llamada, quiero anular la primera expectativa.

Esto ayudaría a simplificar enormemente mi escenario de prueba.

Respuesta

67

Existen tres maneras:

Se puede restaurar la expectativas mediante el uso de BackToRecord

tengo que admitir que nunca realmente utilizado, ya que es incómodo.

// clear expectations, an enum defines which 
_stubRepository.BackToRecord(BackToRecordOptions.All); 
// go to replay again. 
_stubRepository.Replay(); 

Editar: Ahora uso a veces, en realidad es la manera más limpia. Debería haber un método de extensión (como Stub) que lo haga, creo que simplemente se olvidó. Sugeriría que escribas el tuyo.

Puede utilizar Repeat.Any()

Es rompe 'el fin de la definición son cortos y se "Anulaciones" de las definiciones anteriores. Pero de alguna manera está implícito. Lo uso a veces porque es fácil de escribir.

_stubRepository.Stub(x => x.Contains(null)) 
    .IgnoreArguments() 
    .Return(false) 
    .Repeat.Any(); 

Puede crear un nuevo simulacro de

trivial, pero explícito y fácil de entender. Solo es un problema si desea mantener muchas definiciones y solo cambiar una llamada.

_stubRepository = MockRepository.GenerateMock<IRepository>(); 
_stubRepository.Stub(x => x.Contains(null)) 
    .IgnoreArguments() 
    .Return(false); 
+0

En Rhino interno hablar, utilizando Repetir. Cualquiera crea una expectativa repetible, que supera las expectativas normales durante la reproducción. Sin embargo, recomiendo usar BackToRecord. –

+0

Ah, lo resolvió todo a excepción de la llamada a Replay(). –

+1

Esto es algo que solo conocen las personas que usan RhinoMocks desde hace 3.4 o más. RhinoMocks trabajó con Record-Replay, esto significa que un simulacro tuvo que establecerse en modo de reproducción explícitamente. Con 3.5, afortunadamente, esto se ha ido, los simulacros siempre están en modo de reproducción (al menos para el código personalizado). Hasta que lo vuelva a poner en el modo de grabación, excepto para despejar las expectativas, no veo ninguna razón para hacerlo. Ya quería escribir un parche para estas dos líneas para restablecer cómodamente las expectativas. –

22

Para estas situaciones, he creado un método simple extensión RinoMocks para mostrar mejor la intención del talón y promover la lectura.

public static void OverridePrevious<T>(this IMethodOptions<T> options) 
{ 
    options.Repeat.Any(); 
} 

Así que en lugar de una llamada críptica como la siguiente que puede requerir un comentario:

[SetUp] 
public void Setup() 
{ 
    carStub.Stub(x => x.Model).Return("Model1"); 
    carStub.Stub(x => x.Model).Return("Model2"); 
} 

[Test] 
public void SomeTest() 
{ 
    //Arrange 
    //overrides previous stubs that were setup for the Model property 
    carStub.Stub(x => x.Model).Return(null).Repeat.Any(); 

    //Act 
    //Assert 
} 

, usted puede obtener una prueba más fácil de leer que muestra mejor la intención de la .Repeat.Any() llama :

carStub.Stub(x => x.Model).Return(null).OverridePrevious(); 
+5

Para mantener la opción abierta para encadenar la configuración de stub, ¿no debería el método de extensión devolver un IMethodOptions ? 'public static IMethodOptions OverridePrevious (this IMethodOptions options) {return options.Repeat.Any(); } ' – PHeiberg

+2

@PHeiberg - No lo he probado o he tenido la necesidad de mantener la 'cadena abierta', pero sí, supongo que tienes razón. Buen punto. – MoMo

+0

Me gusta OverridePrevious como vacío, lo fuerza hasta el final. – user2864740

5

Por el bien de la comunidad voy a añadir a añadir a la lista de opciones anteriores de Stefan:

Si el valor de retorno debe cambiarse con frecuencia, me resulta limpio y eficiente utilizar un cierre de la siguiente manera.

bool returnValue = true; 
_stubRepository.Stub(x => x.Contains(null)).IgnoreArguments().Do(new Func<bool>(() => { 
    return returnValue; 
})); 

returnValue = false; 
// Calls to Contains now return false; 

returnValue = true; 
// Calls to Contains now return true; 

La expresión lambda se ejecuta cada vez que se llama Contains y porque hemos creado un cierre returnValue referencia, siempre va a buscar el valor actual de returnValue.

+0

Esta es la solución más limpia en mi opinión –

Cuestiones relacionadas