.ashx接口单元测试

      最近项目中需要修改一个文件上传的.ashx处理,代码的大概形式是这样的:

public void ProcessRequest(HttpContext context)
{
   CallA(context);
}

     方法CallA中直接使用了context并做了很多业务判断,也没有时间重构此方法,因此想对修改的代码做单元测试,

就需要Mock或实例化context参数。
     提示:我们开发环境为vs2010,mock组件为moq,当然有条件使用moles或是mvc的情况下,做这个单元测试还是比较容易的

     由于HttpContext是密封类,Moq就显得无力了,那就只有自己实例化了,从网上发现了有个帮助类,心中暗喜

https://svn.re-motion.org/svn/Remotion/branches/1.8/Web/UnitTests/AspNetFramework/HttpContextHelper.cs

在此感谢作者的无私的贡献。直到使用后发现一个问题,这个帮助类只支持对querystring,form,session的赋值,

而项目中却需要对context.Request.ServerVariables和context.Request.Files赋值(文件上传嘛,你懂的),

于是作为码农的我就开始堆代码了

下面是设置服务端参数的函数的实现:

        public static void SetServerVar(HttpContext context, NameValueCollection vars)
        {
            System.Collections.Hashtable hash = new System.Collections.Hashtable();

            Type entryType = typeof(System.Collections.Specialized.NameObjectCollectionBase).GetMethod("FindEntry", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).ReturnType;
            Type p = typeof(System.Web.HttpApplication).Assembly.GetType("System.Web.HttpServerVarsCollectionEntry");

            foreach (string key in vars)
            {
                var httpServerVarsCollectionEntry = PrivateInvoke.CreateInstanceNonPublicCtor(p, new object[] { key, vars[key] });

                var entry = PrivateInvoke.CreateInstanceNonPublicCtor(entryType, new object[] { key, httpServerVarsCollectionEntry });

                hash[key] = entry;
            }
            PrivateInvoke.SetNonPublicField(context.Request.ServerVariables, "_entriesTable", hash);
            PrivateInvoke.SetNonPublicField(context.Request.ServerVariables, "_allKeys", new string[] { "server_name" });
        }

下面是设置上传文件的代码:

        public static void SetFile(HttpContext context, string formName, string contentType, string fileName, byte[] file)
        {
            Type httpInputStream = typeof(HttpPostedFile).GetConstructors(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)[0].GetParameters()[2].ParameterType;

            Type httpRawUploadedContent = httpInputStream.GetConstructors(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)[0].GetParameters()[0].ParameterType;

            var row = PrivateInvoke.CreateInstanceNonPublicCtor(httpRawUploadedContent, new object[] { file.Length, file.Length });
            PrivateInvoke.SetNonPublicField(row, "_data", file);
            PrivateInvoke.SetNonPublicField(row, "_length", file.Length);
            PrivateInvoke.SetNonPublicField(row, "_completed", true);

            var stream = PrivateInvoke.CreateInstanceNonPublicCtor(httpInputStream, new object[] { row, 0, file.Length });

            HttpPostedFile f = (HttpPostedFile)PrivateInvoke.CreateInstanceNonPublicCtor(typeof(HttpPostedFile), new object[] { fileName, contentType, stream });

            PrivateInvoke.InvokeNonPublicMethod(context.Request.Files, "AddFile", new object[] { formName, f });
        }

代码我就不解释了,没什么技术含量。在此建议在写函数时尽量减少依赖性,如上面的CallA方法传入的是业务参数,也就没有这些问题了

最后,附上源码及demo,猛击我下载

 

转载于:https://www.cnblogs.com/luanfei/p/3269942.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值