Moq,模拟抽象类:模拟对象不能使用抽象类中实现的方法

发布于 2025-01-11 19:31:10 字数 827 浏览 0 评论 0原文

嗨,我有一个类似于以下内容的代码:

        public abstract class MyAbstractClass
        {
            public virtual string DoSomething(string s1, string s2)
            {
                return this.DoSomethingElse(s1 + s2);
            }

            protected abstract string DoSomethingElse(string s);
        }


        [TestMethod]
        public void Test()
        {
            var myMock = new Mock<MyAbstractClass>();
            myMock.Protected().Setup<string>("DoSomethingElse", ItExpr.IsAny<string>()).Returns<string>(x => $"{x} I did it.");

            var result = myMock.Object.DoSomething("a", "b");

        }

我希望测试中的结果是“ab我做到了”,但我得到了一个空值。我注意到,如果删除“DoSomething”方法中的“虚拟”,它会按预期返回。问题是我需要这个方法是虚拟的。老实说,根据我对起订量如何工作的理解,它应该返回“ab我做到了”,但也许我错过了一些东西。

有什么想法吗?谢谢

hi I have a code similar to the following:

        public abstract class MyAbstractClass
        {
            public virtual string DoSomething(string s1, string s2)
            {
                return this.DoSomethingElse(s1 + s2);
            }

            protected abstract string DoSomethingElse(string s);
        }


        [TestMethod]
        public void Test()
        {
            var myMock = new Mock<MyAbstractClass>();
            myMock.Protected().Setup<string>("DoSomethingElse", ItExpr.IsAny<string>()).Returns<string>(x => 
quot;{x} I did it.");

            var result = myMock.Object.DoSomething("a", "b");

        }

I would expect the result in the test to be "ab I did it", but I get back a null. I noticed that if remove the "virtual" to the "DoSomething" method, than it would return as expected. The problem is that I need this method to be virtual. And honestly in my understanding of how moq work it should return the "ab I did it", but maybe I am missing something.

Any idea? Thanks

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

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

发布评论

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

评论(1

九厘米的零° 2025-01-18 19:31:10

原因是因为您正在使用模拟对象调用 DoSomething 方法,但是因为您没有告诉模拟对象使用真正的实现或 Setup 它默认情况下只是“不执行任何操作”(即返回 null)。

解决此问题的快速方法是为模拟对象设置 CallBase = true 属性。然后,任何不是 Setup 的方法都将使用真正的实现。

var myMock = new Mock<MyAbstractClass>() { CallBase = true };
myMock
    .Protected()
    .Setup<string>("DoSomethingElse", ItExpr.IsAny<string>())
    .Returns("DoSomethingElseResult");

Console.WriteLine("DoSomething: " + myMock.Object.DoSomething("a", "b"));

这将打印“DoSomething: DoSomethingElseResult”,这应该正是您想要的。模拟对象使用真实实现来运行 DoSomething,而 DoSomething 的真实实现则运行 DoSomethingElse 的模拟实现。

The reason is because you're calling the DoSomething method using the mock object, but because you haven't told the mock object to use the real implementation or Setup it, it's just going to "do nothing" (ie return null) by default.

The quick way to solve this is by setting the CallBase = true property for the mock object. Then, any method that isn't Setup will use the real implementation.

var myMock = new Mock<MyAbstractClass>() { CallBase = true };
myMock
    .Protected()
    .Setup<string>("DoSomethingElse", ItExpr.IsAny<string>())
    .Returns("DoSomethingElseResult");

Console.WriteLine("DoSomething: " + myMock.Object.DoSomething("a", "b"));

This will print "DoSomething: DoSomethingElseResult", which should be exactly what you want. The mock object runs DoSomething using the real implementation, and the real implementation of DoSomething runs the mocked implementation of DoSomethingElse.

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