【发布时间】:2019-01-15 16:04:34
【问题描述】:
我正在写HttpModule 并且需要测试它,我正在使用C#、.NET4.5.2、NUnit 和Moq。
我要测试的方法是Context_BeginRequest:
public class XForwardedForRewriter : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += Context_BeginRequest;
}
public void Context_BeginRequest(object sender, EventArgs e) { ... }
}
sender 这里是HttpApplication,这是问题开始的地方,...可以创建HttpApplication 的实例,但是无法设置HttpContext,因为它是只读的并且没有办法传递它(通过构造函数或类似的东西)...
我没有VS2015 Ultimate,也无法使用Microsoft.Fakes (Shims),而ATM 是我找到的唯一解决方案is to create a wrapper,这听起来不像是最直接的解决方案... .
当我想到这一点时,我确信有人已经遇到了这个确切的问题(因为每次在 TDD 中写 HttpModule 时,他都需要模拟 HttpApplication 或做一些解决方法)
如何测试事件IHttpModules?有没有办法模拟 HttpApplication? 最好使用Moq。
编辑:这是我要测试的代码...它是从PROXY v2二进制到旧X-Forwarded-For的标头重写器...
public class XForwardedForRewriter : IHttpModule
{
public void Dispose()
{
throw new NotImplementedException();
}
byte[] proxyv2HeaderStartRequence = new byte[12] { 0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A };
public void Init(HttpApplication context)
{
context.BeginRequest += Context_BeginRequest;
}
public void Context_BeginRequest(object sender, EventArgs e)
{
var request = ((HttpApplication)sender).Context.Request;
var proxyv2header = request.BinaryRead(12);
if (!proxyv2header.SequenceEqual(proxyv2HeaderStartRequence))
{
request.Abort();
}
else
{
var proxyv2IpvType = request.BinaryRead(5).Skip(1).Take(1).Single();
var isIpv4 = new byte[] { 0x11, 0x12 }.Contains(proxyv2IpvType);
var ipInBinary = isIpv4 ? request.BinaryRead(12) : request.BinaryRead(36);
var ip = Convert.ToString(ipInBinary);
var headers = request.Headers;
Type hdr = headers.GetType();
PropertyInfo ro = hdr.GetProperty("IsReadOnly",
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.FlattenHierarchy);
ro.SetValue(headers, false, null);
hdr.InvokeMember("InvalidateCachedArrays",
BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
null, headers, null);
hdr.InvokeMember("BaseAdd",
BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
null, headers,
new object[] { "X-Forwarded-For", new ArrayList { ip } });
ro.SetValue(headers, true, null);
}
}
}
【问题讨论】:
-
你到底想测试什么?显示 SUT,也许可以找到解决方法。
标签: c# unit-testing nunit moq httpmodule