编辑:我的业务逻辑与显示逻辑分开,我的业务逻辑有1或2个公共方法可供窗体访问,但是关于业务逻辑中的所有私有方法呢?
单元测试图形应用程序的关键是确保所有业务逻辑都在一个单独的类中,而不是在代码后面。
设计模式,如模型视图展示器和模型视图控制器,在设计这样的系统时可以提供帮助。
举个例子:
public partial class Form1 : Form, IMyView
{
MyPresenter Presenter;
public Form1()
{
InitializeComponent();
Presenter = new MyPresenter(this);
}
public string SomeData
{
get
{
throw new NotImplementedException();
}
set
{
MyTextBox.Text = value;
}
}
private void button1_Click(object sender, EventArgs e)
{
Presenter.ChangeData();
}
}
public interface IMyView
{
string SomeData { get; set; }
}
public class MyPresenter
{
private IMyView View { get; set; }
public MyPresenter(IMyView view)
{
View = view;
View.SomeData = "test string";
}
public void ChangeData()
{
View.SomeData = "Some changed data";
}
}
[TestMethod]
public void TestChangeData()
{
IMyView view = MockRepository.DynamickMock<IMyView>();
view.Stub(v => v.SomeData).PropertyBehavior();
MyPresenter presenter = new MyPresenter(view);
presenter.ChangeData();
Assert.AreEqual("Some changed data", view.SomeData);
}
将所有业务逻辑拆分为单独的项目,并对其进行单元测试。或者至少将所有表单中的逻辑移动到单独的类中。
使用approvaltests(www.approvaltests.com或nuget)对View进行单元测试非常简单。这里有一个视频:http://www.youtube.com/watch?v=hKeKBjoSfJ8
然而,似乎您也担心将函数设置为默认或公共以便能够测试功能。
这些通常被称为接缝;用于测试代码的方式。它们很好。有时人们会混淆私有/公共和安全性,并害怕将私有函数公开,但是反射将调用任何一个,因此它并不真正安全。其他时候,人们担心类的API接口。但是,只有当您拥有公共API时才会有影响,如果您有一个winform应用程序,则可能意味着它是顶层(没有其他消费者在调用它)。
您是程序员,因此可以设计易于测试的代码。这通常意味着仅需将几个方法更改为公共方法并创建一些方便的方法即可传递依赖项。
例如:
buttonclick += (o,e)=> {/*somecode*/};
很难测试。
private void button1_Click(object sender, EventArgs e) {/*somecode*/}
仍然很难测试
public void button1_Click(object sender, EventArgs e) {/*somecode*/}
private void button1_Click(object sender, EventArgs e) { DoSave();}
public void DoSave(){/*somecode*/}
非常容易测试!
如果您需要从事件中获取一些信息,这将变得更加容易。例如:
public void ZoomInto(int x, int y)
相比于对应的鼠标点击事件,测试它要容易得多,而且透传调用仍然可以是一个可以忽略的单行代码。
人们可以使用MVVM(Model-View-ViewModel)模式与Reactive.UI来编写可测试的WinForms代码,以获得真正需要的关注点分离。请参见:Reactive.UI https://reactiveui.net/ 使用Winforms/MVVM/Reactive.UI的主要缺点是没有太多的使用示例(用于WinForms)。好处在于它适用于几乎所有桌面框架和语言。您可以为一种语言学习它,但其原则适用于所有语言。当你有很多私有方法时,这没关系。个人建议:尝试使用公共方法开始要测试的业务过程。您可以使用“告知,不要询问”:https://martinfowler.com/bliki/TellDontAsk.html,同时保持所有这些方法为私有。
一种测试代码的方法是通过驱动UI进行测试,但这并不是非常推荐的,因为结果测试非常脆弱、难以实现,并且不能像纯代码测试那样精细地编写;最后,如果您使用数据库,您需要考虑用测试数据填充它,并且由于每次测试前必须将数据库置于干净、定义明确的状态,所以您的测试可能比您想象的运行得更慢,因为您需要重新初始化每个测试的数据。