2010-05-04 22 views
5

Estoy tratando de probar la lógica de algunas clases existentes. No es posible volver a factorizar las clases en este momento ya que son muy complejas y están en producción.Rhino Mocks Parcial Mock

Lo que quiero hacer es crear un objeto simulado y probar un método que internamente llama a otro método que es muy difícil de burlar.

Así que quiero establecer un comportamiento para la llamada al método secundario.

Pero cuando configuro el comportamiento para el método, se invoca el código del método y falla.

¿Me está faltando algo o simplemente no es posible probar sin volver a factorizar la clase?

He intentado todos los diferentes tipos de simulacro (Strick, Stub, Dynamic, Parcial ect) pero todos terminan llamando al método cuando trato de configurar el comportamiento.

using System; 
using MbUnit.Framework; 
using Rhino.Mocks; 

namespace MMBusinessObjects.Tests 
{ 
    [TestFixture] 
    public class PartialMockExampleFixture 
    { 
     [Test] 
     public void Simple_Partial_Mock_Test() 
     { 
      const string param = "anything"; 

      //setup mocks 
      MockRepository mocks = new MockRepository(); 


      var mockTestClass = mocks.StrictMock<TestClass>(); 

      //record beahviour *** actualy call into the real method stub *** 
      Expect.Call(mockTestClass.MethodToMock(param)).Return(true); 

      //never get to here 
      mocks.ReplayAll(); 

      //this is what i want to test 
      Assert.IsTrue(mockTestClass.MethodIWantToTest(param)); 


     } 

     public class TestClass 
     { 
      public bool MethodToMock(string param) 
      { 
       //some logic that is very hard to mock 
       throw new NotImplementedException(); 
      } 

      public bool MethodIWantToTest(string param) 
      { 
       //this method calls the 
       if(MethodToMock(param)) 
       { 
        //some logic i want to test 
       } 

       return true; 
      } 
     } 
    } 
} 

Respuesta

14

MethodToMock no es virtual y, por lo tanto, no se puede burlar. Lo que quiere hacer es posible con un simulacro parcial (lo he hecho en casos similares al suyo), pero el método que desea simular debe ser parte de una implementación de interfaz o se debe marcar como virtual. De lo contrario, no se puede burlar con Rhino.Mocks.

+0

Totalmente extrañado, estás en lo cierto. – tvanfosson

+0

Solo para agregar, no puedes generar un simulacro parcial desde una interfaz. Los métodos que se burlan deben de hecho ser marcados como virtuales. –

1

recomiendo no métodos de burla en la clase bajo prueba, pero su situación puede ser única en la que no se puede refactorizar la clase para que sea más fácil para poner a prueba en la actualidad. Puede intentar crear explícitamente un delegado para evitar que se invoque el método al configurar la llamada.

Expect.Call(delegate { mockTestClass.MethodToMock(param) }).Return(true); 

O, cambie a utilizar la sintaxis AAA, omitiendo las construcciones desaprobadas.

[Test] 
    public void Simple_Partial_Mock_Test() 
    { 
     const string param = "anything"; 

     var mockTestClass = MockRepository.GenerateMock<TestClass>(); 

     mockTestClass.Expect(m => m.MethodToMock(param)).Return(true); 

     //this is what i want to test 
     Assert.IsTrue(mockTestClass.MethodIWantToTest(param)); 

     mockTestClass.VerifyAllExpectations(); 
    } 
+0

La sintaxis AAA debería funcionar bien. +1 para usarlo. –

+0

Gracias por su ayuda, intenté con lo que dijo, pero en este ejemplo simple todavía arroja la excepción en la línea mockTestClass.Expect (m => m.MethodToMock (param)) .Return (true); llama a las clases MethodToMock que arrojarán una NotImplementedException. –

+0

MethodToMock debe ser virtual – jannagy02

Cuestiones relacionadas