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

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

问题描述

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

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.

最后,有一些框架,例如: TypeMock JustMock 可直接与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天全站免登陆