;
mockHandler.Setup(c => c.AuthorizedRoles)
.Returns(new string[] { "admin", "user" }).Verifiable();
try
{
mockHandler.Object.ProcessRequest(mockContext.Object);
}
catch
{
throw;
}
finally
{
mockContext.Verify();
mockHandler.Verify();
}
}
这是测试身份验证通过,而基于角色的授权失败时的情况。我们把IsAuthenticated设为 true,并且要求IsInRole方法在“接受到任何string类型参数”的时候都返回false,而最后 再“象征性”地设置AuthorizedRoles所返回的内容。这个测试的期望是抛出 UnauthorizedAccessException,不过值得注意的是,我们的代码还有其他要求,那就是要求 IsInRole和AuthorizedRoles一定要调用过——您明白了吗?这就是为什么对Mock对象追加 Verifiable和Verify方法,并且使用try/catch/finally的缘故。
[TestMethod()]
public void ProcessRequestTest_Authorized_Request()
{
Mock<HttpContextBase> mockContext = new Mock<HttpContextBase>(MockBehavior.Strict);
mockContext.Setup(c => c.User.Identity.IsAuthenticated).Returns (true);
mockContext.Setup(c => c.User.IsInRole(It.IsAny<string> ())).Returns(false);
mockContext.Setup(c => c.User.IsInRole("user")).Returns (true).Verifiable();
Mock<AuthorizedHandler> mockHandler = new Mock<AuthorizedHandler> { CallBase = true };
mockHandler.Setup(c => c.ProcessRequestCore (It.IsAny<HttpContextBase>()))
.AtMostOnce().Verifiable();
mockHandler.Setup(c => c.AuthorizedRoles).Returns(new string[] { "admin", "user" })
.Verifiable();
mockHandler.Object.ProcessRequest(mockContext.Object);
mockHandler.Verify();
mockContext.Verify();
}
最后的测试自然是正常流程的测试。在这里我们要检验的是正常情况下 ProcessRequestCore是否“被调用,而且只被调用了一次”。如果您能够理解前两个测试, 这个测试应该也同样简单才是。
UrlRewriteModule
之前都是在测试Http Handler,不过Http Module的测试也较为类似。其原则是相同的: 把所有逻辑转发给针对抽象的方法。我们这次就以最最经典的URL重写功能为例,如下:
public interface IUrlRewriteSource
{
string GetRewritePath(string rawUrl);
}
public class UrlRewriteModule : IHttpModule
{
public void Dispose() { }
public UrlRewriteModule()
: this(new RegexUrlRewriteSource(...))
{ }
internal UrlRewriteModule(IUrlRewriteSource source)
{
this.m_source = source;
}
private IUrlRewriteSource m_source;
public void Init(HttpApplication httpApp)
{
httpApp.BeginRequest += (sender, e) =>
{
HttpContext context = ((HttpApplication)sender).Context;
this.TryRewritePath(new HttpContextWrapper(context));
};
}
internal void TryRewritePath(HttpContextBase context)
{
string newUrl = this.m_source.GetRewritePath (context.Request.R
|