最近项目中需要修改一个文件上传的.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)[].GetParameters()[].ParameterType; Type httpRawUploadedContent = httpInputStream.GetConstructors(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)[].GetParameters()[].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, , 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,猛击我下载

.ashx接口单元测试的更多相关文章

  1. .Net Core ----通过XUnit进行接口单元测试(带请求头及参数)并用output输出结果

    最近在做core的接口单元测试,所以在这拿出来分享一下,添加XUnit的nuget包 话不多说,直接上代码了: 输出结果(需要的命名空间using Xunit.Abstractions;): ITes ...

  2. 51.Qt-使用ajax获取ashx接口的post数据

    由于当前C++项目需要使用ajax库去post调用ashx接口,接口地址如下所示: 需要传递的参数如下: 然后发现qml比较好调用ajax.js库,所以本章通过C++界面去获取qml方法来实现调用as ...

  3. Rest接口单元测试

    Get请求url不超过4000字节 Rest成熟度:level 0:使用http作为传输方式,leve 1:引入资源概念,每个资源有对应的url,level 2:使用http方法进行不同操作,使用ht ...

  4. 安卓端后台登录接口单元测试demo

    package com.js.ai.modules.pointwall.interfac; import java.io.IOException; import java.io.Unsupported ...

  5. 一起买beta版模块单元测试

    一起买beta版模块接口单元测试 测试目的 保证代码质量,对各个模块进行单元测试,不仅可以有效地保证代码的可靠性,让模块在与别的模块整合时出现更少的错误. 而且不用每次启动程序而等待浪费时间. 单元描 ...

  6. 基于python+Testlink+Jenkins实现的接口自动化测试框架V3.0

    基于python+Testlink+Jenkins实现的接口自动化测试框架V3.0 目录 1. 开发环境2. 主要功能逻辑介绍3. 框架功能简介 4. 数据库的创建 5. 框架模块详细介绍6. Tes ...

  7. 8点了解Java服务端单元测试

    一. 前言 单元测试并不只是为了验证你当前所写的代码是否存在问题,更为重要的是它可以很大程度的保障日后因业务变更.修复Bug或重构等引起的代码变更而导致(或新增)的风险. 同时将单元测试提前到编写正式 ...

  8. Mock测试你的Spring MVC接口

    1. 前言 在Java开发中接触的开发者大多数不太注重对接口的测试,结果在联调对接中出现各种问题.也有的使用Postman等工具进行测试,虽然在使用上没有什么问题,如果接口增加了权限测试起来就比较恶心 ...

  9. RhinoMock初探

    官方wiki:http://www.ayende.com/wiki/Rhino+Mocks.ashx ========================================= 接口Mock: ...

随机推荐

  1. DNS中A记录和CNAME记录的区别(转)

    A记录是域名到ip的映射,即为ip起别名:CNAME是域名别名到域名的映射,即为域名起别名. 还有一个常用的记录是MX记录,它是与邮件相关的,MX记录记录了发送电子邮件时域名对应的服务器地址. 原文: ...

  2. 将expression转化为数据类型int时发生算术溢出错误

    在SQL Server 中,某列的数据都在int范围之内,但是使用sum聚集函数求该列和的时候,出现“将expression转化为数据类型int时发生算术溢出错误”. 问题在于定义的数据类型: 首先, ...

  3. IScroll5中文API整理,用法与参考

    IScroll是移动页面上被使用的一款仿系统滚动插件.IScroll5相对于之前的IScroll4改进了许多,使得大家可以更方便的定制所需的功能了. 做项目的时候正好用到了这个插件,自己做了一下总结, ...

  4. android studio 使用CMAKE

    前言 之前,每次需要边写C++代码的时候,我的内心都是拒绝的.  1. 它没有代码提示!!!这意味着我们必须自己手动敲出所有的代码,对于一个新手来说,要一个字母都不错且大小写也要正确,甚至要记得住所有 ...

  5. sdut 迷之容器(线段树+离散化)

    #include <iostream> #include <algorithm> #include <string.h> #include <stdio.h& ...

  6. centos上yum安装nodeJS

    更新node.js各版本yum源 Node.js v8.x安装命令 curl --silent --location https://rpm.nodesource.com/setup_8.x | ba ...

  7. linux 定时备份

    每部主机的任务都不相同,重要的数据也不相同,重要性也不一样,因此,每个人癿备份思考角度都不一样! 有些备份策略是非常有趣的: (1)挂载储存设备进行备份: 挂载设备: 备份的 script #!/bi ...

  8. (27)Cocos2d-x 3.0 Json用法

    Cocos2d-x 3.0 加入了rapidjson库用于json解析.位于external/json下. rapidjson 项目地址:http://code.google.com/p/rapidj ...

  9. in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)

    最近在用ruby的一些库的时候,总是出现这个错误. 在使用net/imap库的时候,或者net/http库(主要是用到了https,https是用了ssl) 的时候,具体如下: 错误提示:E:/Rub ...

  10. AVAudioFoundation(4):音视频录制

    本文转自:AVAudioFoundation(4):音视频录制 | www.samirchen.com 本文主要内容来自 AVFoundation Programming Guide. 采集设备的音视 ...