单元测试自定义AuthorizationFilterAttribute

时间:2017-01-13 07:42:12

标签: c# unit-testing authorization

我们做了自定义授权属性,并且希望它被单元测试覆盖。不幸的是,我不知道如何对这类员工进行单元测试。你能告诉我吗?

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身份。

1 个答案:

答案 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。