Moq,SetupGet,模拟属性

Posted

技术标签:

【中文标题】Moq,SetupGet,模拟属性【英文标题】:Moq, SetupGet, Mocking a property 【发布时间】:2012-08-21 22:19:43 【问题描述】:

我正在尝试模拟一个名为UserInputEntity 的类,其中包含一个名为ColumnNames 的属性:(它确实包含其他属性,我只是针对问题对其进行了简化)

namespace CsvImporter.Entity

    public interface IUserInputEntity
    
        List<String> ColumnNames  get; set; 
    

    public class UserInputEntity : IUserInputEntity
    
        public UserInputEntity(List<String> columnNameInputs)
        
            ColumnNames = columnNameInputs;
        

        public List<String> ColumnNames  get; set; 
    

我有一个演示者类:

namespace CsvImporter.UserInterface

    public interface IMainPresenterHelper
    
        //...
    

    public class MainPresenterHelper:IMainPresenterHelper
    
        //....
    

    public class MainPresenter
    
        UserInputEntity inputs;

        IFileDialog _dialog;
        IMainForm _view;
        IMainPresenterHelper _helper;

        public MainPresenter(IMainForm view, IFileDialog dialog, IMainPresenterHelper helper)
        
            _view = view;
            _dialog = dialog;
            _helper = helper;
            view.ComposeCollectionOfControls += ComposeCollectionOfControls;
            view.SelectCsvFilePath += SelectCsvFilePath;
            view.SelectErrorLogFilePath += SelectErrorLogFilePath;
            view.DataVerification += DataVerification;
        


        public bool testMethod(IUserInputEntity input)
        
            if (inputs.ColumnNames[0] == "testing")
            
                return true;
            
            else
            
                return false;
            
        
    

我尝试了以下测试,在其中模拟实体,尝试获取 ColumnNames 属性以返回初始化的 List&lt;string&gt;() 但它不起作用:

    [Test]
    public void TestMethod_ReturnsTrue()
    
        Mock<IMainForm> view = new Mock<IMainForm>();
        Mock<IFileDialog> dialog = new Mock<IFileDialog>();
        Mock<IMainPresenterHelper> helper = new Mock<IMainPresenterHelper>();

        MainPresenter presenter = new MainPresenter(view.Object, dialog.Object, helper.Object);

        List<String> temp = new List<string>();
        temp.Add("testing");

        Mock<IUserInputEntity> input = new Mock<IUserInputEntity>();

    //Errors occur on the below line.
        input.SetupGet(x => x.ColumnNames).Returns(temp[0]);

        bool testing = presenter.testMethod(input.Object);
        Assert.AreEqual(testing, true);
    

我得到的错误表明存在一些无效参数 + 参数 1 无法从字符串转换为

System.Func<System.Collection.Generic.List<string>>

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

ColumnNamesList&lt;String&gt; 类型的属性,因此在设置时需要在Returns 调用中传递List&lt;String&gt; 作为参数(或返回List&lt;String&gt; 的函数)

但是通过这一行,你试图只返回一个string

input.SetupGet(x => x.ColumnNames).Returns(temp[0]);

这是导致异常的原因。

将其更改为返回整个列表:

input.SetupGet(x => x.ColumnNames).Returns(temp);

【讨论】:

看来我需要休息一下。非常感谢您的帮助! (+1 n 将在 7 分钟内接受你的回答) SetupGet() 是我正在寻找的。谢谢! 和我一样,使用 SetUpGet() 作为类属性,它可以工作。【参考方案2】:

模拟只读属性意味着只有getter方法的属性。

注意要声明为virtual,否则会抛出System.NotSupportedException

如果您使用的是界面,则不适用于您。它可以立即工作,因为模拟框架会为您即时实现接口。

【讨论】:

那么如何在接口中将只读属性声明为虚拟? @erict 如果你使用接口,则不需要指定 virtual,因为接口方法默认是虚拟的

以上是关于Moq,SetupGet,模拟属性的主要内容,如果未能解决你的问题,请参考以下文章

使用最小起订量模拟静态属性

为啥我要模拟的属性需要是虚拟的?

如何使用 MOQ 框架在 c# 中模拟静态方法?

如何使用 moq 模拟 ConfigurationManager.AppSettings

使用 Moq 模拟扩展方法

使用 Moq 模拟 NHibernate ISession