开发者

c# Mocking Interface members of a concrete class with Moq

开发者 https://www.devze.com 2022-12-16 17:14 出处:网络
I have an interface ITransaction as follows: public interface ITransaction { DateTime EntryTime { get; }

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

b开发者_如何学编程ut 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.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消