有没有办法创建一个模拟对象,只模拟其中一个属性,并让其他人

时间:2014-12-16 08:40:12

标签: c# tdd moq

有没有办法创建一个模拟对象,只模拟其中一个属性,让其他属性(属性和方法)链接到原始类,而不必模拟所有方法

测试方法 - >

var test= new Mock<Test>().As<ITest>();
test.CallBase = true;
test.SetupGet(m => m.DateNow).Returns(DateTime.Now.AddDays(10));
double num= test.Object.Calc();

界面 - &gt;

public interface ITest
{
double Calc();
DateTime DateNow { get; }
}

类 - &gt;

public class Test : ITest
{
 public DateTime DateNow
        {
            get
            {
                return DateTime.Now.Date;
            }
        }
public double Calc(){
DateTime d = DateTime.Now.AddDays(100);
return (DateNow - d).TotalDays;
}

始终为num = 0.0;

1 个答案:

答案 0 :(得分:5)

是的,您可以,只要您确实使用CallBase来调用具体类,并As<>来定位适当的接口/基类:

var mockClass = new Mock<MyClass>().As<IMyInterface>();
mockClass.CallBase = true;
mockClass.SetupGet(m => m.Property1).Returns("Mock");

Assert.AreEqual("Mock", mockClass.Object.Property1);
Assert.AreEqual("MyClass", mockClass.Object.Property2);

在这组实体上进行了测试:

public interface IMyInterface
{
    string Property1 { get; set; }
    string Property2 { get; set; }
}

public class MyClass : IMyInterface
{

    public string Property1
    {
        get { return "MyClass"; }
        set {  }
    }

    public string Property2
    {
        get { return "MyClass"; }
        set { }
    }
}

修改

为什么我的具体类不能多态调用Mocked重写属性?

这并不是特定于Moq的 - 请注意,类的接口的默认实现是sealed。如果您打算对类属性进行多态行为,则需要将该属性实现为virtual,如下所示:

public interface ITest
{
    DateTime DateNow { get; set; }
    double Calc();
}

public class Test : ITest
{
    public virtual DateTime DateNow // ** NB : Virtual
    { // ....

修改

这应该会更清晰 - 在DateNow上使用和不使用虚拟关键字时尝试此操作:

var test = new Mock<Test>().As<ITest>();
test.CallBase = true;
test.SetupGet(m => m.DateNow).Throws(new NotImplementedException());
double num = test.Object.Calc();