简体   繁体   中英

c# Mocking Interface members of a concrete class with Moq

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.

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.

你是在嘲笑一个具体的类,所以我猜你只能模拟虚拟的成员(它们必须是可覆盖的)。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM