首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

测试中,自己怎么创建mock对象

2013-09-26 
测试中,自己如何创建mock对象一个类 A,我要对它某方法(取名为x)的代码进行测试,在x中会创建 窗口 B,并且执

测试中,自己如何创建mock对象
一个类 A,我要对它某方法(取名为x)的代码进行测试,在x中会创建 窗口 B,并且执行B中的y方法。
代码如下:
ClsA.cs
    class ClsA
    {
        public void x()
        {
            FrmB oF = new FrmB();
            oF.y();

            int j = 0;
            int k = 5 / j;
        }
    }

FrmB.cs
    public partial class FrmB : Form
    {
        public FrmB()
        {
            InitializeComponent();
        }

        public void y()
        {
            MessageBox.Show("运行了很多复杂代码!");
        }
    }

测试代码ClsATest.cs
        /// <summary>
        /// x 的测试
        /// </summary>
        [TestMethod()]
        public void xTest()
        {
            ClsA target = new ClsA();
            target.x();
        }

这个测试存在的问题:在ClsA.x()中,启动了 FrmB ,并且“运行了很多复杂代码!”。
[解决办法]
你管别人说什么“足够好”呢?你到底想用它干什么实际的事情呢?
------解决方案--------------------


只因为你是在重复造轮子。
[解决办法]
如果你注重测试的话,应该先写测试代码,再写实际程序,这样就会强迫你在写实际程序时为测试留好接口。

在ClsA中用new FrmB()这样的写法,就表示ClsA和FrmB是紧密联系在一起的。FrmB的改变可能会影响ClsA,如果想复用ClsA的话,ClsA也必须和FrmB一起作为一个整体被引用。而通过构造函数传递IfFrmB接口这种IoC/DI方式,则ClsA和FrmB没有直接联系。只要IfFrmB接口稳定,对FrmB的修改不影响ClsA。

[解决办法]

引用:
我这几天调整出来的实际的结构,仍然按我对 MessageBox 的处理那样。先按几个原则:一、代码测试覆盖率追求100%;二、测试一个方法,不测试它调用的“复杂”方法(例如会产生用户操作的,弹出界面的,代码较多的,相关类较多的)。
用一个静态测试属性来表明当前处于测试状态,对于复杂方法,直接使用测试员预计的值返回(预计一个方法返回值应该不是困难的事情)。这样测试某个“方法A”时,测试员列出对复杂方法的预计值,这样测试代码跳过这些复杂方法直接返回预计值,我们就可以达到仅测试“方法A”本身。
存在的问题就是,因为判断是否在测试状态,所以代码覆盖率就不可能达到100%。

如果你测试的方法位于业务层,它本来就应该和界面是分离的。不应该在测试时用开关来跳过这些UI方法的调用,而是应该设计时就采用依赖注入的方式,把UI作为一个服务接口传到这个方法所在的类,测试时也很容易伪造一个ui的mock对象,提供一些假的输入,来测试这个方法的各种分支。
而UI本身的测试,通常是用ui automation工具,来模拟鼠标、键盘的操作,看界面的反应是否正常,这个和一般的代码测试是不同的。

热点排行