我无法使用Moq框架模拟我的Form的两个属性。有一些例子说明了我在做什么,但是它们都是类型简单的属性,如string
或int
。
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
...
}
...
#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
。谢谢。
答案 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
};
}
上面的代码段不会抛出异常并让您访问添加的项目......