С# Mocking Интерфейсные элементы конкретного класса с Moq
У меня есть интерфейс ITransaction следующим образом:
public interface ITransaction {
DateTime EntryTime { get; }
DateTime ExitTime { get; }
}
и у меня есть производный класс PaymentTransaction следующим образом:
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
}
Я хотел бы Mock все три свойства объекта PaymentTransaction.
Я пробовал следующее, но он не работает:
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);
но когда я вставляю
(mockedTxn.Object как PaymentTransaction)
в методе, который я тестирую (поскольку он принимает только PaymentTransaction, а не ITransaction, я не могу его изменить), отладчик показывает нулевую ссылку для времени входа и выхода.
Мне было интересно, может ли кто-нибудь помочь мне.
Спасибо в ожидании.
Ответы
Ответ 1
Единственные способы, с помощью которых я мог обойти эту проблему (и это похоже на хак в любом случае) - либо делать то, что вы не хотите делать, а сделать свойства на конкретном классе виртуальными (даже для реализация интерфейса), а также явно реализовать интерфейс в вашем классе. Например:
public DateTime EntryTime
{
get { return ((ITransaction)this).EntryTime; }
}
DateTime ITransaction.EntryTime
{
get { throw new NotImplementedException(); }
}
Затем, когда вы создаете свой макет, вы можете использовать синтаксис As<ITransaction>()
, и макет будет вести себя так, как вы ожидаете.
Ответ 2
Вы издеваетесь над конкретным классом, поэтому, я думаю, вы сможете только высмеять членов, которые являются виртуальными (они должны быть переопределяемыми).