使用最小起订量测试 WinForms MVP 和事件机制
我一直在我的应用程序中使用 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 be Stub正常工作。 欢迎任何建议。 提前致谢。 问候, Vajda
编辑:当我创建 SubscribeOnClick(EventHandler click); 时,我能够做到这一点;我的 IButton 界面中的方法而不是事件 EventHandler Click。我在我记得方法的地方做了一些 ButtonMock 。但是,如果有人知道更好的解决方案,请与我分享。
I've been using MVP pattern in my application. But I have problems with testing my method which are called after button is clicked. Here is the code:
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";
}
}
The problem is that I don't know how to write test so that my ButtonClick method get called. I tried like this:
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);
I think that problem is in this line:
this.view.Button1.Click += ButtonClick;
It seems that Click event doesn't remember ButtonClick method. How to make Click to be stub to work just normal.
Any suggestion is welcome.
Thanks in advance.
Regards,
Vajda
EDIT: I was able to do that when I created SubscribeOnClick(EventHandler click); method in my IButton interface instead of event EventHandler Click. And I made some ButtonMock where I remembered method. But still, if someone knows for better solution, please share with me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
也许在这里使用命令模式并不是一个坏主意。您的
IView
是非常特定于实现的,因为它具有规定数量的控件,这些控件应该具有Click
事件(我知道这是一个示例,但仍然......)。命令模式的一个简单实现是让
IView
具有由演示者提供的List
,并让视图的特定实现决定如何触发这些操作,例如通过执行A 模拟对象不需要有 Click 事件(Moq 甚至可能不支持,我不确定)。你可以让它触发其中一项操作。
Maybe it's not a bad idea to use the command pattern here. Your
IView
is very implementation specific because it has a prescribed number of controls that should have aClick
event (I know it is an example, but still...).A simple implementation of the command pattern would be to let
IView
have aList<Action>
that is supplied by the presenter, and let a specific implementation of a view decide how to fire these actions, e.g. by doingA mock object would not need to have a Click event (which may not even be supported by Moq, I'm not sure). You could just have it fire one of its actions.
我将 IButton 接口更改为以下接口:
这样我就能够制作存根类,该存根类具有我可以订阅的私有事件,并在调用方法之后在需要时触发事件。
I Changed my IButton interface to this one:
This way I was able to make stub class which have private event where I can subscribe and after that call method which fires event when needed.