如何使用Moq在没有setter的情况下初始化复杂属性?

时间:2015-09-08 00:20:09

标签: c# .net nunit moq

问题:

我无法使用Moq框架模拟我的Form的两个属性。有一些例子说明了我在做什么,但是它们都是类型简单的属性,如stringint

Fields的{​​{1}}属性没有像IMainForm那样被初始化,这对我来说是有意义的(接口不允许这种类型的初始化发生)。我只是不知道如何克服它。

我的表格定义如下:

MainForm

在我的测试中,我的夹具设置如下:

public partial class MainForm : XtraForm, IMainForm
{
    ...

    #region Public Properties

    public RichEditDocumentServer DocServer { get; } = new RichEditDocumentServer();

    public Dictionary<string, string> Fields { get; } = new Dictionary<string, string>();

    #endregion

    ...
}

我的测试失败的行(但是当我使用UI运行时通过):

...
#region Private Variables

private Mock<IConnector> _arc = new Mock<IConnector>();
private Mock<IMainForm> _arForm = new Mock<IMainForm>();
private MainController _controller;

#endregion

[TestFixtureSetUp]
public void FixtureSetup()
{
    _arc.SetupAllProperties();
    _arForm.SetupAllProperties();
    _controller = new MainController(_arc.Object)
    {
        View = _arForm.Object
    };
}
...

意向:

我不希望我的表单的公共接口允许将View.Fields.Add(...) // throws NullReferenceException because Fields in null Fields属性设置为除最初设置之外的其他属性。但是这仍然允许在DocServer属性上调用.Add(...)。我打算测试将Fields添加到KeyValuePair是成功实现更多业务逻辑类型的事情的步骤。

问题:

在没有setter的情况下初始化复杂属性的 Moq 方式是什么?我的测试失败,因为这些属性是Fields。谢谢。

1 个答案:

答案 0 :(得分:5)

你必须使用SetupGet方法;此方法用于处理您想要模拟getter方法的情况。(您可以使用常规Setup代替SetupGet ...)

作为@Jeppe Stig Nielsen的注释,您可以设置方法,以便在每次调用时返回新实例或返回相同的实例。在您的情况下,您正在寻找选项B:

    private Mock<IConnector> _arc;
    private Mock<IMainForm> _arForm;
    private MainController _controller;
    private Dictionary<string, string> _fields;

    [TestFixtureSetUp]
    public void FixtureSetup()
    {
        _fields = new Dictionary<string, string>();
        _arc = new Mock<IConnector>();
        _arForm = new Mock<IMainForm>();

        //The magic line:
        _arForm.SetupGet(x => x.Fields).Returns(_fields);

        _controller = new MainController(_arc.Object)
        {
            View = _arForm.Object
        };
    }

上面的代码段不会抛出异常并让您访问添加的项目......