C# 使用MVC模式对Winforms进行单元测试?

C# 使用MVC模式对Winforms进行单元测试?,c#,asp.net-mvc,winforms,unit-testing,C#,Asp.net Mvc,Winforms,Unit Testing,需要创建小型winform应用程序供我的公司私人使用,以便与我们的数据库交互。时期我知道.NETMVC有一个非常成熟的MVC模式单元测试框架,就像我想做TDD一样 因此,在下面给出的教程中,是否可以使用NUnit或其他简单/成熟的单元测试框架(编辑:基于我使用ASP.NET的经验)?我已经在谷歌上搜索并查看了我的技术书籍库,对于如何对winforms进行有效的单元测试,明显缺乏文档。因此,我转向这个论坛,希望个人能与我分享他们的领域知识 我发现的大多数建议是MVC模式(我同意),但不是如何解决w

需要创建小型winform应用程序供我的公司私人使用,以便与我们的数据库交互。时期我知道.NETMVC有一个非常成熟的MVC模式单元测试框架,就像我想做TDD一样

因此,在下面给出的教程中,是否可以使用NUnit或其他简单/成熟的单元测试框架(编辑:基于我使用ASP.NET的经验)?我已经在谷歌上搜索并查看了我的技术书籍库,对于如何对winforms进行有效的单元测试,明显缺乏文档。因此,我转向这个论坛,希望个人能与我分享他们的领域知识

我发现的大多数建议是MVC模式(我同意),但不是如何解决winform的具体问题。例如,如何测试一个按钮的点击和该按钮的后续操作


我计划使用C#VS13.net4.5。我很高兴加入这个资源,并将贡献给所有回答我的问题。谢谢

单元测试不适用于UI。当然你可以这样做,但我不推荐这样做,因为有几个原因:你不能单元测试DPI变化、多屏幕、程序在不同窗口状态下的行为,或者如果用户在控件之间移动制表器会发生什么。单元测试UI只会给您错误的安全性


如果愿意,可以使用UI自动化工具自动测试UI,但不要进行单元测试。您可以使UI层尽可能薄,这也是一种很好的设计实践。您可以对winforms应用程序中使用的其他类使用单元测试。

正如您可能已经注意到的,这里的想法是使用界面描述视图

因此,控制器实际上不需要窗口,它需要一个实现接口的类

因此,您可以有另一个视图接口的自动模拟或手动实现,它不涉及WinForms子系统,而是公开数据以编写断言

有了存根视图,您只需针对它编写一个脚本。您从类中公开了一些方法,这些方法允许您自动化交互:

public class ViewStub : IView
{
    // implement the view interface as it is but also
    // an extra stuff to let you automate this in your unit tests

    public void RaiseButtonClick()
    {
        this.controller.DoTheButtonClickStuff();
    }
}
然后您的测试变成(我遵循教程中的约定)


单元测试GUI是独立于所使用的GUI库的东西。一般案例的答案也适用于您的案例:

GUI的单元测试是通过最小化依赖于GUI框架的类的占用空间来完成的。然后仍然依赖于GUI框架的类没有进行单元测试(这与“未测试”完全不同)。这些类是MVP、MVC、MVVM等模式中的“视图”


结论:每一个好的.Net单元测试框架都是一个好的WinForms单元测试框架。您在问题中提到的NUnit就是这样一个框架的一个例子。

“.Net MVC有一个非常成熟的单元测试框架”?-注意清楚你的意思。(假设MVC==ASP.NETMVC).Net没有针对ASP.NETMVC的任何特定单元测试框架。。。VisualStudio中有一个通用测试框架,但它没有特定于ASP.NETMVC的内容,也没有任何特定的堆栈(WPF/WinForms/WebForms…)。将演示者与依赖项分离并测试演示者。其他人似乎也有类似的问题:@Smith.h.Neil:他知道这一点,因为这就是他链接中的教程的全部内容。他只是不知道如何“分离[…]并测试演示者”。请看我的答案。使用WPF代替MVVM模式。您可以测试ViewModels和Models,如果不使用任何代码,甚至不需要测试视图,因为测试不应该给您100%的安全感,而是验证基本功能并快速发现问题。想要对UI进行单元测试没有什么错。问题是这样做通常很困难。@Mino:你说的不是真的。MVC(或一些人称之为MVP)或MVVM是为单元测试ui应用程序而设计的体系结构模式。不是测试实际的用户界面,而是测试用户操作应用程序时应用程序的行为。另一方面,你的建议也很重要,有些互补性。这就像白盒/黑盒测试。这就是我投反对票的原因,你的回答听起来像是在劝阻他做一些完全有效的事情。我知道单元测试不会涵盖任何内容。在问题的第三条评论中有一个指向Michael Feathers文档的链接,我想这也是在试图说你不应该对UI层进行单元测试。如果你留下一个没有测试的薄UI层,它不会对你造成太大的伤害。如果您使用TDD样式编码,并从UI层开始测试。我认为它将引导您轻松地将代码直接写入UI层。同时,连接UI也会让人头疼。在我看来,做一些缓慢的事情,仅仅测试几个方法调用是浪费时间。使用为特定任务设计的工具,不要只使用你知道的工具。考虑到你的措辞,我认为这对NUnit是可行的。例如,假设buttonclick增加了一个计数器。我可以执行上面的脚本,然后断言计数器增加了1,或者其他什么。对如果是这样的话,开始变得超级兴奋。这可能有效。:)
ViewStub form = new ViewStub();
IModel mdl = new IncModel();
IController cnt = new IncController(view,mdl);

form.RaiseButtonClick();