为什么我会收到带有消息“非虚拟(在 VB 中可覆盖)成员上的无效设置..."的异常? [英] Why am I getting an Exception with the message "Invalid setup on a non-virtual (overridable in VB) member..."?

查看:12
本文介绍了为什么我会收到带有消息“非虚拟(在 VB 中可覆盖)成员上的无效设置..."的异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个单元测试,我必须模拟一个返回 bool 类型的非虚拟方法

I have a unit test where I have to mock a non-virtual method that returns a bool type

public class XmlCupboardAccess
{
    public bool IsDataEntityInXmlCupboard(string dataId,
                                          out string nameInCupboard,
                                          out string refTypeInCupboard,
                                          string nameTemplate = null)
    {
        return IsDataEntityInXmlCupboard(_theDb, dataId, out nameInCupboard, out refTypeInCupboard, nameTemplate);
    }
}

所以我有一个 XmlCupboardAccess 类的模拟对象,我试图在我的测试用例中为这个方法设置模拟,如下所示

So I have a mock object of XmlCupboardAccess class and I am trying to setup mock for this method in my test case as shown below

[TestMethod]
Public void Test()
{
    private string temp1;
    private string temp2;
    private Mock<XmlCupboardAccess> _xmlCupboardAccess = new Mock<XmlCupboardAccess>();
    _xmlCupboardAccess.Setup(x => x.IsDataEntityInXmlCupboard(It.IsAny<string>(), out temp1, out temp2, It.IsAny<string>())).Returns(false); 
    //exception is thrown by this line of code
}

但是这一行抛出异常

Invalid setup on a non-virtual (overridable in VB) member: 
x => x.IsDataEntityInXmlCupboard(It.IsAny<String>(), .temp1, .temp2, 
It.IsAny<String>())

有什么建议可以解决这个异常吗?

Any suggestion how to get around this exception?

推荐答案

Moq 不能模拟非虚拟方法和密封类.在使用模拟对象运行测试时,MOQ 实际上会创建一个内存中代理类型,该类型继承自您的XmlCupboardAccess"并覆盖您在SetUp"方法中设置的行为.正如您在 C# 中所知道的那样,只有在将某些内容标记为虚拟时才能覆盖某些内容,而在 Java 中则不然.默认情况下,Java 假定每个非静态方法都是虚拟的.

Moq cannot mock non-virtual methods and sealed classes. While running a test using mock object, MOQ actually creates an in-memory proxy type which inherits from your "XmlCupboardAccess" and overrides the behaviors that you have set up in the "SetUp" method. And as you know in C#, you can override something only if it is marked as virtual which isn't the case with Java. Java assumes every non-static method to be virtual by default.

我认为您应该考虑的另一件事是为您的CupboardAccess"引入一个界面,然后开始模拟该界面.它将帮助您解耦代码并从长远来看有好处.

Another thing I believe you should consider is introducing an interface for your "CupboardAccess" and start mocking the interface instead. It would help you decouple your code and have benefits in the longer run.

最后,有如下框架:TypeMockJustMock 直接与 IL 一起工作,因此可以模拟非虚拟方法.然而,两者都是商业产品.

Lastly, there are frameworks like : TypeMock and JustMock which work directly with the IL and hence can mock non-virtual methods. Both however, are commercial products.

这篇关于为什么我会收到带有消息“非虚拟(在 VB 中可覆盖)成员上的无效设置..."的异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆