2010-05-04 3 views
5

Я пытаюсь проверить логику из некоторых существующих классов. В настоящее время невозможно перегруппировать классы, поскольку они очень сложны и производятся.Rhino Mocks Partial Mock

Что я хочу сделать, это создать макет объекта и протестировать метод, который внутренне вызывает другой метод, который очень сложно издеваться.

Так что я хочу просто установить поведение для вызова вторичного метода.

Но когда я настраиваю поведение метода, код метода вызывается и терпит неудачу.

Я что-то упустил или это просто невозможно проверить без повторного факторинга класса?

Я пробовал все разные типы макетов (Strick, Stub, Dynamic, Partial ect.), Но все они в конечном итоге вызывают метод, когда я пытаюсь настроить поведение.

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

ответ

14

МетодToMock не является виртуальным и, следовательно, не может быть издевательством. То, что вы хотите сделать, возможно с частичным макетом (я делал это в случаях, подобных вашим), но метод, который вы хотите издеваться, должен быть либо частью реализации интерфейса, либо быть помечен как виртуальный. В противном случае вы не можете издеваться над ним с Rhino.Mocks.

+0

Полностью пропустил это - вы абсолютно правы. – tvanfosson

+0

Просто чтобы добавить, вы не можете генерировать частичный макет из интерфейса. Методы издевательства должны быть действительно отмечены виртуальными. –

1

Я рекомендую не методы насмешливой в классе под испытанием, но ваша ситуация может быть уникальной в том, что вы не можете реорганизовать класс, чтобы сделать его проще для тестирования в настоящее время. Вы можете попытаться явно сделать делегат, чтобы предотвратить вызов метода при настройке вызова.

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

Или переключитесь на использование синтаксиса AAA, опуская устаревшие конструкции.

[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

Синтаксис AAA должен работать нормально. +1 для его использования. –

+0

Спасибо за вашу помощь, я попробовал то, что вы сказали, но в этом простом примере он по-прежнему выбрасывает исключение в строке mockTestClass.Expect (m => m.MethodToMock (param)) .Return (true); вызывает классы MethodToMock, которые будут вызывать исключение NotImplementedException. –

+0

МетодToMock должен быть виртуальным – jannagy02