2

Is there a way to create a mock object and only mock one of the Property, and let the others (Properties and Methods) links to the original class, without having to mock all the methods

Test Method -->

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();

Interface -->

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

Class -->

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;
}

Always num = 0.0;

Ahmed Assaf
  • 601
  • 7
  • 25
  • 1
    Can't you just create new class that inherits from real class and then override the single property? –  Dec 16 '14 at 08:41
  • @pwas : Doing this will complex the Architecture and this is only for test Purpose. – Ahmed Assaf Dec 16 '14 at 09:52

1 Answers1

5

Yes, you can, provided that you do make use of both CallBase to call into the concrete class, and As<> to target the appropriate interface / base class:

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);

As tested on this set of entities:

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 { }
    }
}

Edit

Why doesn't my concrete class polymorphically call the Mocked overridden property?

This isn't really Moq specific - Note that the default implementation of an interface by a class is sealed. If you intend polymorphic behaviour on your class properties, you'll need to implement the property as virtual, like so:

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

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

Edit

This should make it even clearer - try this with and without the virtual keyword on DateNow:

var test = new Mock<Test>().As<ITest>();
test.CallBase = true;
test.SetupGet(m => m.DateNow).Throws(new NotImplementedException());
double num = test.Object.Calc();
Community
  • 1
  • 1
StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • I make the above solution but it doesn't work the return is 0.0 and the excepted is -1 – Ahmed Assaf Dec 16 '14 at 09:01
  • Please edit your post with your code. I'm guessing you don't have a base interface or virtual properties on a base class? If so, note that these can't be Moq'd. You would need Moles / Fakes / Typemock to do this. – StuartLC Dec 16 '14 at 09:04
  • I have interface and no virtual Properties But I'm mocking a property and calling Method depending on that property from Mock.Object.Calc(); – Ahmed Assaf Dec 16 '14 at 09:14
  • I have added the virtual to the property and no effect. – Ahmed Assaf Dec 16 '14 at 09:39
  • 1
    The concrete class returns ~-100, and the Mocked property returns -90? – StuartLC Dec 16 '14 at 09:42