2009-07-11 10 views
2

我有一个叫做Common的属性的TxRx类。常见的有一个名为LastMod的属性。我想写一个RhinoMock的期望来表明LastMod已经设置了一些东西。所以,我想:RhinoMocks中的产业链

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

我相信,这意味着公共需要是虚拟的,但因为它是一个LinqToSql产生类的属性我不能使其成为虚拟的(除了黑客的自动代码,这不是一个真正的选择)。

有没有办法解决这个问题?

回答

1

一种可能性是将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; } 
    ... 
} 

不理想(即它可以得到有点麻烦了传递的包装只是为了mockability!),但是这是你能得到RhinoMocks嘲笑的属性/方法的唯一途径您。

另一种选择是使用TypeMock而不是我认为使用不同的机制来嘲笑的东西。不过,我认为它不是免费的。

0

您需要与

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

但共同的属性本身来代替你的第二个期望需要被虚拟了这个工作。

+0

这不会编译,它需要Lambda表达式进行编译。我同意,看起来Common需要是虚拟的,这正是我想要避免的。好吧。 –

+0

现在已经修复了这个问题。 –