tags:

views:

390

answers:

2

I have a class TxRx with a property called Common. Common then has a property called LastMod. I want to write a RhinoMock expectation to show that LastMod has been set with something. So I tried:

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

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

But I get the following exception:

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 ...

I presume this means Common needs to be virtual, but as it is a property on a LinqToSql generated class I can't make it virtual (other than hacking the autogen code which is not really an option).

Is there any way around this?

A: 

You would need to replace your second expectation with

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

But the Common property itself needs to be virtual for this to work.

David M
This does not compile, it needs the Lambda expression to compile. I agree that it looks like Common needs to be virtual, that is what I was trying to avoid. Oh well.
Colin Desmond
Have fixed this now.
David M
+1  A: 

One possibility is to wrap TxRx in a mockable class (i.e. one that has overridable methods and properties which you wish to mock out or implements an interface which defines the properties or methods that you're interested in) and then pass around the wrapper rather than the LinqToSQL class itself.

Perhaps something like the following:

public class TxRxWrapper : ITxRxWrapper
{
    private TxRx m_txrx;

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

    ...
}

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

Not ideal (i.e. it can get somewhat cumbersome to pass wrappers around just for mockability!) but that's the only way you can get RhinoMocks to mock properties/methods for you.

The other option is to use TypeMock instead which I believe uses a different mechanism to mock stuff out. I don't think it's free, though.

jpoh