我们做了自定义授权属性,并且希望它被单元测试覆盖。不幸的是,我不知道如何对这类员工进行单元测试。你能告诉我吗?
public override void OnAuthorization(HttpActionContext actionContext)
{
var ts = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(TokenService));
try
{
var token = GetHeader(actionContext.Request);
if (token == null)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
Content = new StringContent("Token not found")
};
return;
}
else
{
var tks = ts as TokenService;
var tkn = Task.Run(() => tks.FindToken(token)).Result;
if (tkn.ValidTill > DateTime.Now)
{
var us = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(UserService));
var uss = us as UserService;
var user = Task.Run(() => uss.FindByTokenValue(token)).Result;
if (user != null)
{
if (!_roles.Contains(user.RoleName))
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content = new StringContent("You role permission is not enough")
};
return;
}
var identity = new Identity { Name = user.Login, IsAuthenticated = true };
var principal = new GenericPrincipal(identity, new[] { user.RoleName });
actionContext.RequestContext.Principal = principal;
Thread.CurrentPrincipal = principal;
base.OnAuthorization(actionContext);
_roles = null;
}
else
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
Content = new StringContent("User not found")
};
return;
}
}
else
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
Content = new StringContent($"Token valid till {tkn.ValidTill}")
};
return;
}
}
}
catch (Exception ex)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
Content = new StringContent($"Authorization error: {ex.Message}")
};
return;
}
}
应该传递的测试: - 令牌存在。 - 令牌对此DateTime有效。 - 用户角色有效。 附:请不要问我为什么这样做而不是使用ASP.NET Identity,这不是我的解决方案,我更喜欢ASP.NET身份。
答案 0 :(得分:0)
这没有什么特别之处。例如,使用Moq:
[Test]
public void OnAuthorization_ReturnsErrorWhenThereIsNoToken()
{
var resolver = new Mock<IDependencyResolver>();
resolver.Setup(x => x.GetService(It.IsAny<Type>())).Returns(
(Type t) =>
{
if (t == typeof(TokenService))
{
return new TokenService();
}
if (t == typeof(TokenService))
{
return new UserService();
}
return null;
});
var original = GlobalConfiguration.Configuration.DependencyResolver;
GlobalConfiguration.Configuration.DependencyResolver = resolver.Object;
var ctx = new HttpActionContext
{
ControllerContext =
new HttpControllerContext { Request = new HttpRequestMessage() }
};
var target = new Attrr();
target.OnAuthorization(ctx); // no token
Assert.AreEqual(HttpStatusCode.Unauthorized, ctx.Response.StatusCode);
Assert.AreEqual("Token not found", (ctx.Response.Content as StringContent).ReadAsStringAsync().Result);
// we need this to ensure the test state is restored after test
GlobalConfiguration.Configuration.DependencyResolver = original;
}
显然,你需要保持复制行为(我希望你的TokenService和UserService实际上是interface
d。