C# Linq中的单元测试虚拟方法

C# Linq中的单元测试虚拟方法,c#,linq,unit-testing,rhino-mocks,C#,Linq,Unit Testing,Rhino Mocks,我需要对以下类结构进行单元测试: public interface IFoo { int Value { get;} int GetValue(); } public class BaseClass : IFoo { public virtual int Value { get { return 100; } } public virtual int GetValue() { return Value; } } public c

我需要对以下类结构进行单元测试:

public interface IFoo
{
    int Value { get;}
    int GetValue();
}

public class BaseClass : IFoo
{
    public virtual int Value { get { return 100; } }
    public virtual int GetValue()
    {
        return Value;
    }
}

public class ChildClass : BaseClass, IFoo
{
    public override int GetValue()
    {
        return Value;
    }
}
我正在尝试用Rhinomock测试ChildClass.GetValue()方法

我有以下存根代码:

public ChildClass CreateChildClass(int value)
{
   var childClass = MockRepository.GenerateStub<ChildClass>();
   childClass.Stub(x => x.Value).Return(value);
   return childClass;            
}
public子类CreateChildClass(int值)
{
var childClass=MockRepository.GenerateStub();
Stub(x=>x.Value).Return(Value);
返回子类;
}
以及以下UnitTest代码:

public IEnumerable<IFoo> CreateList()
{
   yield return CreateChildClass(1000);
   yield return CreateChildClass(2000);
}

[TestMethod]
public void virtualMethodTest()
{
   var list = CreateList();
   var query = from p in list
               select p.GetValue(); //I can't use p.Value

   var sum = query.Sum(p => p);
 }
public IEnumerable CreateList()
{
收益率收益率(1000);
收益率收益率(2000);
}
[测试方法]
public void virtualMethodTest()
{
var list=CreateList();
var query=来自列表中的p
选择p.GetValue();//我不能使用p.Value
var sum=query.sum(p=>p);
}
目前的问题是总和总是零。我可以快速查看列表,并从CreateList()中看到两个具有正确值的模拟对象

可以在子类上对虚方法进行单元测试吗?或者我需要使用不同的RhinoMocks方法吗

谢谢两件事:

  • 您正在创建具体类的存根,而不是IFoo。mock在其内部工作中具有高度的反射性,因此多态调用的行为可能相同,也可能不同,这取决于框架和调用的确切性质
  • 您正在创建存根,根据其性质,存根将忽略对其接口进行的任何不期望的调用(返回返回类型的默认值)。这是你问题的直接原因;GetValue()不是预期值,因此它返回默认整数值(0)
您希望测试实际类的某些行为,但要覆盖某些其他行为(副作用,不在测试范围内,等等)。RhinoMocks中的基本答案是PartialMock,它将默认为实际类的行为,除非您希望进行某个调用。因此,创建MockRepository的一个实例并实例化一个新的MockRepository.PartialMock()而不是GenerateSub()。期望您要覆盖的内部行为,但不要触及其他任何内容。您可能必须使用较旧的录制和播放方法;我通常使用的Rhinomock版本在实例化PartialMock并在实例上调用Expect()时表现不正确

这一变化将大致如下:

//instantiate Mocks in class scope, as an instance of MockRepository

public ChildClass CreateChildClass(int value)
{
   var childClass = Mocks.PartialMock<ChildClass>();
   childClass.Expect(x => x.Value).Return(value);
   return childClass;            
}
//在类范围内实例化mock,作为MockRepository的实例
公共子类CreateChildClass(int值)
{
var childClass=Mocks.PartialMock();
Expect(x=>x.Value).Return(Value);
返回子类;
}