views:

328

answers:

2

I have an interface ITransaction as follows:

public interface ITransaction {

        DateTime EntryTime { get; }

        DateTime ExitTime { get; }
}

and I have a derived class PaymentTransaction as follows:

public class PaymentTransaction : ITransaction {

        public virtual DateTime LastPaymentTime
        {
            get { return DateTime.Now; }
        }

        #region ITransaction Members

        public DateTime EntryTime
        {
            get  { throw new NotImplementedException(); }
        }

        public DateTime ExitTime
        {
            get  { throw new NotImplementedException(); }
        }

        #endregion
}

I wanted to Mock all three properties of PaymentTransaction Object.

I have tried the following, but it doesnt work:

var mockedPayTxn = new Mock<PaymentTransaction>();
mockedPayTxn.SetUp(pt => pt.LastPaymentTime).Returns(DateTime.Now); // This works

var mockedTxn = mockedPayTxn.As<ITransaction>();
mockedTxn.SetUp(t => t.EntryTime).Returns(DateTime.Today); 
mockedTxn.SetUp(t => t.ExitTime).Returns(DateTime.Today); 

but when I inject

(mockedTxn.Object as PaymentTransaction)

in the method I am testing (as it is only takes a PaymentTransaction and not ITransaction, I can't change it either) the debugger shows null reference for entry time and exit time.

I was wondering if someone could help me please.

Thanks in anticipation.

A: 

You're mocking a concrete class, so I guess you'll only be able to mock members that are virtual (they must be overridable).

Wayne
I understand that I am mocking a concrete class, but given the fact that entry and exit time props are the interface members and I am casting my concrete mocked object to interface, I shouldnt need to make these props virtual. I was just wondering if there was any other way to do this.
Raghu
+2  A: 

The only ways I have been able to get around this issue (and it feels like a hack either way) is to either do what you don't want to do and make the properties on the concrete class virtual (even for the interface implementation), or to also explicitly implement the interface on your class. For instance:

public DateTime EntryTime
{
  get  { return ((ITransaction)this).EntryTime; }
}

DateTime ITransaction.EntryTime
{
  get { throw new NotImplementedException(); }
}

Then, when you create your Mock, you can use the As<ITransaction>() syntax and the mock will behave as you expect.

mkedobbs