c# 使用 Moq 模拟具体类的接口成员

发布于 2024-08-17 22:11:19 字数 1283 浏览 10 评论 0原文

我有一个接口 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,我也无法更改它)调试器显示进入时间和退出时间的空引用。

我想知道是否有人可以帮助我。

感谢期待。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

君勿笑 2024-08-24 22:11:19

我能够解决这个问题的唯一方法(无论哪种方式都感觉像是黑客)是要么做你不想做的事情,要么将具体类的属性设为虚拟(即使对于接口实现) ,或者在您的类上显式实现该接口。例如:

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

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

然后,当您创建模拟时,您可以使用 As() 语法,模拟将按照您的预期运行。

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.

罗罗贝儿 2024-08-24 22:11:19

您正在模拟一个具体的类,所以我想您只能模拟虚拟的成员(它们必须是可重写的)。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文