我在我的应用程序中一直使用MVP模式。但是我在测试我的方法时遇到了问题,这些方法在单击按钮后调用。这是代码:
public interface IControl
{
bool Enabled { get; set; }
string Text { get; set; }
}
public interface IButton : IControl
{
event EventHandler Click;
}
public class Button : System.Windows.Forms.Button, IButton
{ }
public interface IForm : IControl
{
void Show();
void Close();
}
public interface IView : IForm
{
IButton Button1 { get; }
}
public partial class View : Form, IView
{
public View()
{
InitializeComponent();
}
#region IView Members
public IButton Button1
{
get { return button1; }
}
#endregion
}
public class Presenter
{
IView view;
public Presenter(IView view)
{
this.view = view;
this.view.Button1.Click += ButtonClick;
this.view.Show();
}
private void ButtonClick(object sender, EventArgs e)
{
view.Button1.Text= "some text";
}
}
问题是我不知道如何编写测试以便调用我的ButtonClick方法。我试过这样:
var view = new Mock<IView>();
view.Setup(x => x.Button1).Returns(new Mock<IButton>().SetupAllProperties().Object);
Presenter presenter = new Presenter(view.Object);
view.Raise(x => x.Button1.Click+= null, EventArgs.Empty);
Assert.AreEqual("some text", view.Object.Button1.Text);
我认为这个问题就在这一行:
this.view.Button1.Click += ButtonClick;
似乎Click事件不记得ButtonClick方法。如何使Click to to stub正常工作。 任何建议都是受欢迎的。 提前致谢。 问候, Vajda
编辑:当我创建SubscribeOnClick(EventHandler click)时,我能够做到这一点;我的IButton界面中的方法而不是事件EventHandler单击。我在记忆方法中制作了一些ButtonMock。但是,如果有人知道更好的解决方案,请与我分享。
答案 0 :(得分:1)
在这里使用command pattern也许不是一个坏主意。您的IView
非常具体,因为它有一定数量的控件,应该有一个Click
事件(我知道这是一个例子,但仍然......)。
命令模式的一个简单实现是让IView
具有由演示者提供的List<Action>
,并让视图的特定实现决定如何触发这些操作,例如:通过做
this.button1.Click += (sender, e) => this.Actions[0]();
模拟对象不需要有Click事件(Moq甚至可能都不支持,我不确定)。你可以让它解雇它的一个动作。
答案 1 :(得分:1)
我将我的IButton界面更改为:
public interface IButton : IControl
{
voie SUbscribeOnClick(EventHandler click);
}
public class ButtonStub : IButton
{
EventHandler click;
public bool Enabled { get; set; }
public void SubscribeOnClick(EventHandler click)
{
this.click = click;
}
public string Text { get; set; }
public void RaiseClickEvent()
{
click(this, EventArgs.Empty);
}
}
通过这种方式,我可以创建存储类,其中包含可以订阅的私有事件,以及在需要时激活事件的调用方法之后。