Насмешливый, виртуальный и многое другое - PullRequest
1 голос
/ 19 сентября 2011

Этот вопрос задавали бы много раз w.r.t к RhinoMocks , но я постараюсь представить немного по-другому. У меня такая ситуация ниже -

class A
{
   X parentOfB;
   A()
   { 
       X parentOfB = someObj;
       if(<something>)
       {
         B objB = parentOfB as B  // NOTE THIS 
         if(objB.Foo)            // call the property here
         {
            // some code ....
         }
       }
   }
}

class B : X
{
   // gets initialised to true somewhere in the program. Don't bother much
   protected bool status ;
   B() {}

   // Property
   public bool Foo
   {
     return status;
   }

}

Mocking: Теперь я хочу сделать что-то вроде этого -

var mock = new MockRepository();

var myObjB = mock.StrictMock<B>();

// call Db class to populate the objB object and then set the expectation as 
// below  
// ...
// ...
Expect.Call(myObjB.Foo).Return(true);
mock.ReplayAll();
var objA = new A();
mock.VerifyAll();

Ошибка: Неверный вызов, последний вызов был использован или не был сделан (убедитесь, что вы вызываете виртуальный (C #) / Overridable (VB) метод).

Проблема в том, что конкретный класс B доступен в ctor of A для доступа к Свойству. Как мне справиться с этим сценарием в RhinoMocks ? Если я сделаю объект Foo виртуальным, он будет работать нормально. Но я не хочу этого делать.

Ответы [ 2 ]

3 голосов
/ 19 сентября 2011

Сначала проверьте трассировку стека исключений и посмотрите, откуда исходит ошибка «неверный вызов». Это происходит от линии Expect.Call? Если это так, удалите класс A с картинки.

Во-вторых, всем макетам требуется способ проверить, было ли вызвано свойство / метод. Они заменяют обычный код свойства / метода некоторым кодом, который записывает, как произошел вызов. Чтобы заменить код, макетируемое свойство или метод должен быть виртуальным или абстрактным, или макет должен быть создан для интерфейса.

0 голосов
/ 19 сентября 2011

Если свойство должно быть смоделировано, а его оригинальное поведение не может быть смоделировано, вот одна из альтернатив. Вы перемещаете код из B.Foo в новое свойство и создаете виртуальную фиктивную замену для B.Foo.

class B
{
    // Old code here
    public bool RealFoo { get { return status; } }

    // New dummy code
    public virtual bool Foo { get { return RealFoo; } }
}

Затем из вашего кода насмешки вы можете записывать, когда вызывается Foo, и вы также можете вызывать "настоящий" код:

var myObjB = mock.StrictMock<B>();

Expect.Call(myObjB.Foo).Return(myObjB.RealFoo);
...