Search code examples
c#mockingrhino-mocksstub

Stub one method of class and let other real methods use this stubbed one


I have a TimeMachine class which provides me current date/time values. The class looks like this:

public class TimeMachine
{
    public virtual DateTime GetCurrentDateTime(){ return DateTime.Now; };
    public virtual DateTime GetCurrentDate(){ return GetCurrentDateTime().Date; };
    public virtual TimeSpan GetCurrentTime(){ return GetCurrentDateTime().TimeOfDay; };
}

I'd like to use TimeMachine stub in my tests in such way that I'd just stub the GetCurrentDateTime method and let the other 2 methods use the stubbed GetCurrentDateTime method so as I don't have to stub all the three methods. I tried to do write the test like this:

var time = MockRepository.GenerateStub<TimeMachine>();
time.Stub(x => x.GetCurrentDateTime())
    .Return(new DateTime(2009, 11, 25, 12, 0, 0));
Assert.AreEqual(new DateTime(2009, 11, 25), time.GetCurrentDate());

But the test fails. GetCurrentDate returns default(DateTime) instead of using GetCurrentDateTime stub internally.

Is there any approach I could use to achieve such behavior or is it just some basic conceptual feature of RhinoMocks I don't catch at the moment? I know I could just get a rid of those two GetDate/Time methods and inline the .Date/.TimeOfDay usage, but I'd like to understand whether this is possible at all.


Solution

  • I just found out that it's possible to achieve this by not using virtual on those two methods - it protects the methods from being overriden when generating stub.

    public class TimeMachine
    {
        public virtual DateTime GetCurrentDateTime(){ return DateTime.Now; };
        public DateTime GetCurrentDate(){ return GetCurrentDateTime().Date; };
        public TimeSpan GetCurrentTime(){ return GetCurrentDateTime().TimeOfDay; };
    }
    

    The test passes now.