Цепочка свойств в RhinoMocks

У меня есть класс TxRx со свойством Common. Затем Common имеет свойство LastMod. Я хочу написать ожидание RhinoMock, чтобы показать, что LastMod был установлен с чем-то. Итак, я попытался:

 var txRx = MockRepository.GenerateMock<TxRx>();
 var common = MockRepository.GenerateMock<Common>();

 txRx.Expect(t => t.Common).Return(common);
 txRx.Expect(t => t.Common.LastMod).SetPropertyAndIgnoreArgument();

Но я получаю следующее исключение:

System.InvalidOperationException: Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method).
   at Rhino.Mocks.LastCall.GetOptions[T]()
   at Rhino.Mocks.RhinoMocksExtensions.Expect[T,R](T mock, Function`2 action)
   at ...

Я предполагаю, что это означает, что Common должен быть виртуальным, но, поскольку это свойство сгенерированного класса LinqToSql, я не могу сделать его виртуальным (кроме взлома кода автогена, что на самом деле не вариант).

Есть ли способ обойти это?


person Colin Desmond    schedule 11.07.2009    source источник


Ответы (2)


Одна из возможностей состоит в том, чтобы обернуть TxRx в мокабельный класс (то есть тот, который имеет переопределяемые методы и свойства, которые вы хотите имитировать, или реализует интерфейс, который определяет интересующие вас свойства или методы), а затем передать оболочку, а не сам класс LinqToSQL.

Возможно что-то вроде следующего:

public class TxRxWrapper : ITxRxWrapper
{
    private TxRx m_txrx;

    public object LastMod 
    {
        get { return m_txrx.Common.LastMod; }
    }

    ...
}

public interface ITxRxWrapper
{
    public object LastMod { get; }
    ...
}

Не идеально (т.е. может быть несколько громоздко передавать обертки только для имитации!), но это единственный способ заставить RhinoMocks имитировать свойства/методы для вас.

Другой вариант - использовать вместо этого TypeMock, который, как я полагаю, использует другой механизм для имитации вещей. Хотя я не думаю, что это бесплатно.

person jpoh    schedule 12.07.2009

Вам нужно будет заменить второе ожидание на

txRx.Expect(() => common.LastMod).SetPropertyAndIgnoreArgument();

Но само свойство Common должно быть виртуальным, чтобы это работало.

person David M    schedule 11.07.2009
comment
Это не компилируется, для компиляции требуется лямбда-выражение. Я согласен, что Common должен быть виртуальным, этого я и пытался избежать. Ну что ж. - person Colin Desmond; 11.07.2009