出异常,如果有就输出它的长度。 这个Handler的作用就是这么无聊,只是为了做一个简单的示例。那么对它的单元测试该怎么 做呢?
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ProcessRequestTest_Throw_ArgumentNullException_When_Data_Is_Empty()
{
HttpContext context = new HttpContext(
new HttpRequest("test.aspx", "http://localhost/test.aspx", ""),
new HttpResponse(new StringWriter()));
CountDataHandler handler = new CountDataHandler();
handler.ProcessRequest(context);
}
[TestMethod]
public void ProcessRequestTest_Check_Output()
{
string data = "Hello World";
TextWriter writer = new StringWriter();
HttpContext context = new HttpContext(
new HttpRequest(
"test.aspx",
"http://localhost/test.aspx",
"data=" + HttpUtility.UrlEncode(data)),
new HttpResponse(writer));
CountDataHandler handler = new CountDataHandler();
handler.ProcessRequest(context);
Assert.AreEqual(data.Length.ToString(), writer.ToString(),
"The output should be {0} but {1}.", data.Length, writer.ToString());
}
它的单元测试分两种情况,一是在data字段缺少的情况下需要抛出异常 (ExpectedException),二便是正常的输出。在测试的时候,我们通过HttpContext的一个 构造函数创建对象,而这个构造函数会接受一个HttpRequest和一个HttpResponse对象。 HttpRequest对象构造起来会接受文件名,路径和Query String;而HttpResponse构造时只需 要一个TextWriter用于输出信息。由于我们这个场景过于简单,因此还真够用了。代码比较 简单,意义也很明确,就不多作解释了。
不过很显然,这种简单场景是几乎无法遇到的。如果我们需要POST的情况呢?做不到;如 果我们需要设置UserAgent呢?做不到;如果我们要检查Url Write的情况?做不到——统统 做不到,真啥都别想做。因此我们还是无法使用这种方式进行测试,这第一个例子仅仅是为 了内容“完整性”而加上的。
AuthorizedHandler
这个例子就复杂些了,并且直接来源于老赵以前的某个项目的代码——当然现在为了示例 进行了简化和改造。在项目中我们往往要编写一些Handler来处理客户端的请求,而同时 Handler需要对客户端进行身份验证及基于角色的授权,只有特定角色的客户才能访问 Handler的主体逻辑,否则便抛出异常。而这样的逻辑有其固有的结构,因此我们这类 Handler编写一个公用的父类,这样我们便可使用“模板方法”的形式来补充具体逻辑了。这 个父类的实现如下:
public abstract class AuthorizedHandler : IHttpHandler
{
public bool IsReusable { get { return false; } }
void IHttpHandler.ProcessRequest(HttpContext context)
{
this.ProcessRequest(new HttpContextWrapper(context));
}
internal void ProcessRequest(HttpContextBase context)
{
if (!context.User.Identity.IsAuthenticated)
{
throw new UnauthorizedAccessException();
}
foreach (var role in this.AuthorizedRoles)
{
if (context.User.IsInRole
|