mvc+webapi 单元测试 3.使用Moq模拟AspnetMvc中的Request.Form

 1.前言

    现在这个项目已经有阶段性的模块完成了,所以就想着对这些模块进行单元测试,以保证项目的代码的质量。首先虽然标题是mvc+webapi实质上我只是对mvc进行的测试。用的时候vs的unit test generator(2015自带).至于它版本的安装和介绍在这不做详细介绍。还有其实我也任务单元测试就是个鸡肋。第一它浪费时间,第二他也不能完全保证我的代码完全没有问题,第三我的测试并不能算到的绩效当中去。所以我把它当做对我一个阶段代码的梳理来对待。

2.单元测试建立

  2.1新建单元测试项目

此项目我是把它当作模块插件来处理。

  2.2.添加单元测试类

[TestClass]
    public class mtnfim
    {
    //实例化测试mvc Controller
         mgtController mtn_fim = new mgtController();
        [TestMethod]
        public void IndexTest()
        {
      //调用类中方法
            var ret = mtn_fim.Index() as ViewResult;
            int errcode = testresult.action_result(ret).errcode;
            Assert.AreEqual(0, errcode);
        }
}

  2.3.代码解释如下:

    2.3.1Assert类的使用

    Assert.AreEqual()      测试指定的值是否相等,如果相等,则测试通过;

    AreSame()                  用于验证指定的两个对象变量是指向相同的对象,否则认为是错误

    AreNotSame()             用于验证指定的两个对象变量是指向不同的对象,否则认为是错误

    Assert.IsTrue()         测试指定的条件是否为True,如果为True,则测试通过;

    Assert.IsFalse()           测试指定的条件是否为False,如果为False,则测试通过;

    Assert.IsNull()             测试指定的对象是否为空引用,如果为空,则测试通过;

    Assert.IsNotNull()        测试指定的对象是否为非空,如果不为空,则测试通过;

2.3.2.返回类型的处理

       我项目当中mvc Controller的返回类型有两个JsonResult。ActionrResult.两种,所以针对于assert类的使用显然我要对mvc的返回的对象进行处理。

jsonresult的处理方式:

通过nugt下载ExposedObject把  对象转为dynami然后对其对象进行操作。代码如下。

 var jsonret = mtn_fim.add_feeitem("测试", "cs");
            var ret = Exposed.From(jsonret.Data);
            int errcode = ret.errcode;
            Assert.AreEqual(6002, errcode);

ActionrResult的处理:

相对与jsonresult直接操作返回对象即可,对此我写了一个方法。

 public static class testresult
    {
        public static result<object> action_result(ViewResult ret)
        {
            return ((wx.web.result<object>)(((System.Web.Mvc.ViewResultBase)((ret))).Model));
        }
        public static result apicitroller_result(System.Web.Http.IHttpActionResult action)
        {
            var rs = ((System.Web.Http.Results.OkNegotiatedContentResult<wx.web.result>)
                    (action)).Content;
            return rs;
        }
    }

使用如下:

 var ret = mtn_fim.Index() as ViewResult;
            int errcode = testresult.action_result(ret).errcode;
            Assert.AreEqual(0, errcode);

 3.实现之外的事:

  3.1.数据库初始化

           以上已经初步实现了单元测试的基本实现,但是考虑到单元测试重复测试,我用ef code first动态的数据库创建,和需要测试的数据。

 public void Initialize(FeeDbContext context)
        {
            List<organization> orgs = new List<organization>() { 
                new organization(){oid=1, name="新中新集团1", state=true,reg_time=DateTime.Now},
                new organization(){oid=2, name="山东大学", state=true,reg_time=DateTime.Now},
                new organization(){oid=3, name="浙江大学", state=true,reg_time=DateTime.Now},
                new organization(){oid=4, name="同济大学", state=true,reg_time=DateTime.Now}
            };
            List<fee_item> fim = new List<fee_item>() { 
                new fee_item(){name="电费",code="pow",type= feeItemType.Normal,State=true,Icon="img/jf_dianf.png",sort=0,appid=0,reg_time=DateTime.Now},
                new fee_item(){name="网费",code="net",type= feeItemType.Normal,State=true,Icon="img/jf_wangf.png",sort=1,appid=1,reg_time=DateTime.Now},
                new fee_item(){name="四六级",code="cet",type= feeItemType.Normal,State=true,Icon="img/jf_siliuj.png",sort=2,appid=2,reg_time=DateTime.Now},
                new fee_item(){name="报名费",code="pow",type= feeItemType.Normal,State=true,Icon="img/jf_baomingf.png",sort=3,appid=3,reg_time=DateTime.Now},
                new fee_item(){name="保险费",code="pow",type= feeItemType.Normal,State=false,Icon="img/jf_baox.png",sort=4,appid=4,reg_time=DateTime.Now},
                new fee_item(){name="住宿费",code="pow",type= feeItemType.Normal,State=true,Icon="img/jf_dianf.png",sort=5,appid=5,reg_time=DateTime.Now}
            };
            List<school_power> con_power = new List<school_power>() { 
            new school_power(){oid=1,power_code="ykt",power_id="1",reg_time=DateTime.Now},
            new school_power(){oid=1,power_code="sims",power_id="2",reg_time=DateTime.Now}
            };
            //depts.ForEach(o => context.dept.Add(o));
            orgs.ForEach(o => context.organization.Add(o));
            fim.ForEach(o => context.fee_item.Add(o));
            con_power.ForEach(o => context.control_power.Add(o));
            context.SaveChanges();
        }
   public void initial()
        {
            try
            {
                var context = new FeeDbContext();
                if (context.Database.Exists())
                {
                  
                    context.Database.Delete();
                }
                new List<IDataInitializer<FeeDbContext>>() { 
                        new DataInit4dept()
                    }.Setup<FeeDbContext>(context);
            }
            catch (DbEntityValidationException ex)
            {
                StringBuilder error = new StringBuilder();
                foreach (var item in ex.EntityValidationErrors)
                {
                    foreach (var item2 in item.ValidationErrors)
                    {
                        error.Append(string.Format("{0}:{1}\r\n", item2.PropertyName, item2.ErrorMessage));
                    }
                }
                Console.WriteLine("数据库初始化报错:" + error);
                throw ex;
            }
            catch (Exception e)
            {
                Console.WriteLine("数据库初始化报错:" + e.Message);
                throw e;
            }
        }

    ef code first写好之后就又到单元测试的部分了,所以要想每次执行单元测试内容的时候都执行一下以上内用就要用到单元测试的附属属性: 

    [ClassInitialize()]  在运行类的第一个测试前先运行代码

    [ClassCleanup()]  在运行完类中的所有测试后再运行代码

    [TestInitialize()]   在运行每个测试前先运行代码

    [TestCleanup()]   在运行完每个测试后运行代码

 [ClassInitialize]
        public static void initialdb(TestContext context)
        {
            //初始化数据库
             new DataBuilder().initial();
            //加载webapi bin文件
            apiconfig_factory.Instance.Load_Apis();
        }

运行测试结果如下:

直到这单元测试的实现也就算结束了,但是对于单元测试还有很多东西没有往上写,比如测试模型,覆盖率等等,对于这个项目的测试也不仅限于单元测试,后边的性能测试和ui测试都会抽时间进行总结。

3.使用Moq模拟AspnetMvc中的Request.Form

3.1nuget下载安装moq

3.2.实例

1、比如Request.Form["MingCheng"]为control中需要模拟的内容

2、在单元测试中调用的代码

 var formvalues = new NameValueCollection { { "ST_MingCheng", "" } };//可以选用KeyValuePair
 var request = new NameValueCollection { { "pageIndex", "" } };
 var mockHttpContext = new Mock<HttpContextBase>();
 mockHttpContext.Setup(c => c.Request.QueryString).Returns(request);
 mockHttpContext.Setup(c => c.Request.Form).Returns(formvalues);
 Mock<SMSTemplateController> mockEnterprise = new Mock<SMSTemplateController>();
 var context = new ControllerContext(mockHttpContext.Object, new RouteData(), stc);
 stc.ControllerContext = context;  //设置control的context熟悉
 var result = stc._SMSTemplatelist(); //调用action方法

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

【选择题】Java基础测试题一(10道)

【选择题】Java基础测试题一(10道) 1.下面哪些是合法的变量名? (DEG) A.2variable //不能以数字开头 ...

3898
来自专栏生信技能树

两个神奇的R包介绍,外加实用小抄

认识Tidy Data1.Reshape Data2.Handle Missing Values3.Expand Tables4.split cells一、测...

1314
来自专栏恰同学骚年

设计模式的征途—5.原型(Prototype)模式

相信大多数的人都看过《西游记》,对孙悟空拔毛变出小猴子的故事情节应该都很熟悉。孙悟空可以用猴毛根据自己的形象复制出很多跟自己一模一样的小猴兵出来,其实在设计模式...

663
来自专栏皮振伟的专栏

[linux][kernel]list_del引起的kernle die分析

前言: 构造网络的恶劣环境:中断,恢复,中断,恢复。。。 复现了到kernel die的BUG。经过分析,是对同一个entry执行了两次list_del导致。 ...

4156
来自专栏AI星球

Eclipse中使用JUnit4进行单元测试(整合篇)

我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能很强大,但我们在程序中只用到该函数的一小部分功能,并且经过调试可以确定,这一小部分功能是...

532
来自专栏更流畅、简洁的软件开发方式

我自己写的一个分页控件(源码和演示代码)PostBack分页版 for vs2003、SQL Server

温馨提示: asp.net分页控件已经升级了,基于.net2.0 ,支持多种数据库。 正式命名为:QuickPager Asp.net 2.0 分页控件。 ...

1845
来自专栏林德熙的博客

WPF 开发

如果使用NamedPipeServerStream、Mutex做单实例,需要传入字符串,这时如果传入一个固定的字符串,会在多用户的时候无法使用。

581
来自专栏计算机视觉与深度学习基础

Leetcode 211 Add and Search Word - Data structure design

Design a data structure that supports the following two operations: void addWor...

1815
来自专栏土豆专栏

Java面试之基本概念(一)

首先heap是堆,stack是栈,stack的空间是由操作系统自动分配和释放,heap的空间是手动申请和释放的;heap的空间是手动申请和释放的,heap常用n...

2397
来自专栏TechBox

【iOS】运行时消息传递与转发机制前言(一)对象的消息传递机制 objc_msgSend()(二)消息转发流程参考文章

1104

扫码关注云+社区