2009-03-10 13 views
18

¿Puedo cambiar el comportamiento de un stub durante el tiempo de ejecución? Algo así como:¿Cómo cambiar el comportamiento de los talones?

public interface IFoo { string GetBar(); } 
    [TestMethod] 
    public void TestRhino() 
    { 
     var fi = MockRepository.GenerateStub<IFoo>(); 
     fi.Stub(x => x.GetBar()).Return("A"); 
     Assert.AreEqual("A", fi.GetBar()); 
     fi.Stub(x => x.GetBar()).Return("B"); 
     Assert.AreEqual("B", fi.GetBar()); // Currently fails here 
    } 

Mi ejemplo de código todavía falla en la línea dada, fi.GetBar() sigue devolviendo "A".

¿O hay otro truco para los talones del modelo cuyo comportamiento cambia con el tiempo? Prefiero no recurrir al uso de fi.Stub(...).Do(...).

Ah, probablemente solo necesito una copia impresa del excelente manual para que alguien me golpee en la cabeza con él. Parece que realmente debería ser obvio, pero no puedo encontrarlo.

+0

Pruebe 'fi.Stub (x => x.GetBar()). Devuelve (" A "). Repeat.Once();' y 'fi.Stub (x => x.GetBar()). Return ("B"). Repeat.Once(); ' –

Respuesta

26

ADVERTENCIA

Cambiar el comportamiento de los talones es un olor código!

Por lo general, indica que las pruebas de su unidad son demasiado complicadas, son difíciles de entender y son frágiles, rompiendo fácilmente los cambios correctos de la clase bajo prueba.

Salida:

  • [Patrones de prueba xUnit] [1]
  • [El Arte de las pruebas unitarias] [2]

Así que, por favor: sólo utilizan esta solución si no puedes evitarlo. En mi opinión, este artículo raya con malos consejos; sin embargo, existen situaciones excepcionales en las que realmente lo necesita.


Ah, lo descubrí por mi cuenta. Rhino admite el modo de grabación/reproducción. Si bien la sintaxis AAA siempre mantiene los objetos en el modo de reproducción, podemos pasar a grabar y volver a reproducir solo para borrar el comportamiento del stub.

Se ve un poco hacker, sin embargo ...

public interface IFoo { string GetBar(); } 
    [TestMethod] 
    public void TestRhino() 
    { 
     var fi = MockRepository.GenerateStub<IFoo>(); 
     fi.Stub(x => x.GetBar()).Return("A"); 
     Assert.AreEqual("A", fi.GetBar()); 

     // Switch to record to clear behaviour and then back to replay 
     fi.BackToRecord(BackToRecordOptions.All); 
     fi.Replay(); 

     fi.Stub(x => x.GetBar()).Return("B"); 
     Assert.AreEqual("B", fi.GetBar()); 
    } 

Actualización:

Voy a usar esto en el futuro, así que las cosas se ven un poco más agradable:

internal static class MockExtension { 
    public static void ClearBehavior<T>(this T fi) 
    { 
     // Switch back to record and then to replay - that 
     // clears all behaviour and we can program new behavior. 
     // Record/Replay do not occur otherwise in our tests, that another method of 
     // using Rhino Mocks. 

     fi.BackToRecord(BackToRecordOptions.All); 
     fi.Replay(); 
    } 
} 
+0

Si desea usar la terminología que es n ative a Rhino Mocks, haga que ClearExpectations –

+1

@Richard: El comportamiento agregado con '.Stub' no establece expectativas. Estás pensando en Comportamiento añadido con '.Expect'. –

Cuestiones relacionadas