c # Mocking Интерфейсные члены конкретного класса с Moq - PullRequest
10 голосов
/ 15 января 2010

У меня есть интерфейс 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
}

Я хотел смоделировать все три свойства объекта 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 as PaymentTransaction)

в методе, который я тестирую (поскольку он принимает только PaymentTransaction, а не ITransaction, я тоже не могу его изменить), отладчик показывает нулевую ссылку для времени входа и выхода.

Мне было интересно, может ли кто-нибудь помочь мне, пожалуйста.

Спасибо в ожидании.

Ответы [ 2 ]

3 голосов
/ 15 января 2010

Единственный способ, которым я смог обойти эту проблему (и в любом случае это похоже на взлом), это либо сделать то, что вы не хотите делать, и сделать свойства конкретного класса виртуальными (даже для реализация интерфейса), или также явно реализовать интерфейс в вашем классе. Например:

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

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

Затем, когда вы создаете макет, вы можете использовать синтаксис As<ITransaction>(), и макет будет вести себя так, как вы ожидаете.

0 голосов
/ 15 января 2010

Вы издеваетесь над конкретным классом, так что, я думаю, вы сможете издеваться только над виртуальными членами (их необходимо переопределить).

...