如何使用最小起订量初始化没有 setter 的复杂属性?

How do I initialize complex properties with no setter using Moq?

问题:

我在使用 Moq 框架模拟我的表单的两个属性时遇到问题。有一些关于如何做我想做的事情的例子,但它们都具有简单类型的属性,比如 stringint.

IMainFormFields 属性 没有像 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

    ...
}

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

...
#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
    };
}
...

在我的测试中失败的行(但当我 运行 和 UI 时通过):

View.Fields.Add(...) // throws NullReferenceException because Fields in null

意向:

我不希望我的表单的 public 界面允许将 FieldsDocServer 属性设置为初始设置以外的其他内容。但这仍然允许 .Add(...)Fields 属性 上被调用。我打算测试将 KeyValuePairs 添加到 Fields 是使更多业务逻辑类型的事情发生的成功步骤。

问题:

没有 setter 的 Moq 初始化复杂属性的方法是什么?我的测试失败了,因为这些属性是 null。谢谢。

你必须使用SetupGet方法;此方法的存在是为了处理您想模拟 getter 方法的情况。(您可以使用常规 Setup 而不是 SetupGet...)

作为@Jeppe Stig Nielsen 的评论,您可以将该方法设置为每次调用时 return 一个新实例或 return 同一实例。在您的情况下,您正在寻找选项 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
        };
    }

以上代码片段不会抛出异常并为您提供对添加项目的访问...