单元测试自定义授权属性

时间:2017-05-15 13:50:11

标签: asp.net-mvc unit-testing bdd authorize-attribute

我已经编写了自定义声明授权属性,我想对我编写的代码进行单元测试,但无法找到我在SO上寻找的内容。

例如,这是我的自定义授权属性类:

using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using IPD2.MVC.Interfaces.Providers;
using IPD2.MVC.Providers;

namespace IPD2.MVC.Attribute 
{
    public class ClaimsAuthorizeAttribute : AuthorizeAttribute
    {
        private readonly string _claimValue;
        private readonly string _claimType;
        private readonly ITokenProvider _tokenProvider;

        public ClaimsAuthorizeAttribute(string type, string value)
        {
            _claimType = type;
            _claimValue = value;
            _tokenProvider = new TokenProvider();
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            var jwt = _tokenProvider.ApiToken as JwtSecurityToken;
            if (jwt == null)
            {
                HandleUnauthorizedRequest(filterContext);
            }
            else
            {
                var claim = jwt.Claims.FirstOrDefault(expr => expr.Value == _claimValue);
                var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
                if (authCookie != null)
                {
                    var formsAuthenticationTicket = FormsAuthentication.Decrypt(authCookie.Value);
                    if (formsAuthenticationTicket != null && !formsAuthenticationTicket.Expired)
                    {
                        var roles = formsAuthenticationTicket.UserData.Split(',');
                        HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(formsAuthenticationTicket), roles);
                    }
                }

                if (claim != null)
                {
                    base.OnAuthorization(filterContext);
                }
                else
                {
                    HandleUnauthorizedRequest(filterContext);
                }
            }

        }
    }
}

测试代码

  public class GivenCallingClaimAuthorizationAttribute : SpecsFor<ClaimsAuthorizeAttribute>
    {
        //HttpActionContext actionContext;
        //IPrincipal originalPrincipal;

        protected override void Given()
        {

            SUT = new ClaimsAuthorizeAttribute(ClaimTypes.Role, "ImNotAllowedToUseController :(");

        }

        public class WhenUserIsNotAllowedToAccessController : GivenCallingClaimAuthorizationAttribute
        {
            protected override void When()
            {
                SUT.OnAuthorization(
                    new AuthorizationContext()
                );
            }
        }

        [Test]
        public void ThenAssertSomethingBasedOnCodeInTest()
        {
            //todo: some assert
        }
    }

我已经使用SpecsFor BDD框架编写了这个基本测试类,但我不确定它成功测试它需要什么。

关于如何测试这个的任何想法?如您所见,我正在测试类本身,而不是具有该属性的控制器。我不确定测试它的好方法。

1 个答案:

答案 0 :(得分:0)

如果你想做BDD,请考虑你班级的行为。应该做什么样的事情?

例如,也许它应该: - 授权当前用户
- 过滤机票已过期的用户
- 为授权用户分配正确的角色
- 等等。

让我们说我们要看第二个,因为它很有趣。我会问你,“你能告诉我一张票何时到期的例子吗?”

你说,“是的,超时时间是500毫秒,所以任何比这更早的东西都过期了。”或者你说,“这些是足球比赛的门票,每年都会发出。” (我不知道票是什么,但这次谈话会帮助我解决这个问题。)

那么我们可以写一个例子:

Given we've got a handler for unauthorized tickets
Given Fred's ticket expired on 2017-05-14  
And it's now 2017-05-14   
When we try to authenticate Fred  
Then Fred should not be authenticated  
And the handler should be given Fred's details

接下来我喜欢将这些放在代码中的注释中,并将“should”作为测试的标题。之后,只需设置上下文(在Given中),将其传递给您的代码进行练习(When)并验证结果(Then)。

但是,您可以看到您的Specs框架仅允许一个给定的!这不是很好,因为我已经确定了几个需要不同背景的场景。如果你使用SpecsFor就像你使用它一样,你必须为我的每个场景制作一个类,并且它们不会很容易阅读!

我强烈建议使用第二种风格,然后在评论中开始使用Given,When,Then。

事实上,与全系统BDD场景相比,单元测试的步骤并没有真正重复使用,在这种情况下,不同功能通常会多次调用上下文。代码(或类)的单元倾向于履行一个责任,或者它以这种方式被重构,并且它的上下文不会因为Mocks而流入其他类。

所以,我发现在评论中只有Give,When和Then就足够了。

因此,我建议您切换到“旧学校”的做事方式,我可以在此页面中看到(从下到下),然后从评论开始。看看这对你有什么用。

顺便说一句,如果你真的想要正确地做BDD,那么你想用它的行为示例驱动开发,并逐步填写代码以使这些例子有效,而不是写下来。这本书"Growing Object Oriented Software, Guided By Tests"对你很有帮助。

相关问题