2010-05-04 19 views
5

Sto provando a testare la logica da alcune classi esistenti. Al momento non è possibile ridimensionare le classi in quanto sono molto complesse e in produzione.Rhino Mocks Partial Mock

Quello che voglio fare è creare un oggetto mock e testare un metodo che chiama internamente un altro metodo che è molto difficile da prendere in giro.

Quindi voglio semplicemente impostare un comportamento per la chiamata al metodo secondario.

Ma quando si imposta il comportamento per il metodo, il codice del metodo viene richiamato e non riesce.

Mi manca qualcosa o non è possibile testare senza ricodificare la classe?

Ho provato tutti i diversi tipi di simulazione (Strick, Stub, Dynamic, Partial ect.) Ma tutti finiscono per chiamare il metodo quando provo a impostare il comportamento.

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; 
      } 
     } 
    } 
} 

risposta

14

MethodToMock non è virtuale e pertanto non può essere preso in giro. Quello che vuoi fare è possibile con una simulazione parziale (l'ho fatto in casi simili ai tuoi), ma il metodo che vuoi deridere deve essere parte dell'implementazione dell'interfaccia o essere contrassegnato come virtuale. Altrimenti, non puoi prenderlo in giro con Rhino.Mocks.

+0

Assolutamente mancato - sei assolutamente corretto. – tvanfosson

+0

Solo per aggiungere non è possibile generare un mock parziale da un'interfaccia. I metodi che vengono derisi devono essere effettivamente contrassegnati come virtuali. –

1

vi consiglio non beffardo metodi nella classe in prova, ma la situazione potrebbe essere unico in quanto non è possibile refactoring la classe per rendere più facile per testare attualmente. Potresti provare a fare un delegato in modo esplicito per impedire che il metodo venga richiamato durante l'impostazione della chiamata.

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

Oppure passare all'utilizzo della sintassi AAA, omettendo i costrutti deprecati.

[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 sintassi AAA dovrebbe funzionare correttamente. +1 per usarlo. –

+0

Grazie per il tuo aiuto, ho provato quello che hai detto, ma in questo semplice esempio getta ancora l'eccezione sulla linea mockTestClass.Expect (m => m.MethodToMock (param)) .Return (true); chiama le classi MethodToMock che generano NotImplementedException. –

+0

MethodToMock dovrebbe essere virtuale – jannagy02

Problemi correlati