本文介绍了单元测试,如何设置和Thread.CurrentPrincipal中IsAuthenticated的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我试图执行一个n层应用程序,服务层,存储库层和Web API控制器的单元测试。我的仓库检查的对象Thread.CurrentPrincipal中获取当前用户。这是我有一个问题,当我创建实现类,从继承的IPrincipal它允许我设置IsUserAuthenticated。有没有一种方法来模拟这对我的单元测试。我想在设置Thread.CurrentPrincipal中我实现对象。 ?我怎么会模仿这种方式,用户

 在我RepositoryBase代码,我调用下面,以确定是否用户进行身份验证: 

公共BOOL IsUserAuthenticated
{
{返回((UserPrincipal)校长).Identity.IsAuthenticated; }
}

实际测试看起来像:
Contract.Requires< UserAccessException>(IsUserAuthenticated,非法访问。);




,我揪从下面的UserPrincipal IsUserAuthenticated:

命名空间HeyLetsTrain.Toolkit.Helper.Authentication
{
公共类UserPrincipal:IPrincipal的
{
的IIdentity _identity;
的String [] _role;
串_emailAddress;


公共UserPrincipal(字符串名称,字符串[]的作用)
{
如果(角色!= NULL)
{
_role =新的字符串[role.Length]
_role.CopyTo(角色,0);
的Array.Sort(_role);
}
_identity =新的GenericIdentity(名);
}

公众的IIdentity身份
{
{返回_identity; }
}

公共字符串EmailAddress的
{
{返回_emailAddress; }
集合{this._emailAddress =价值; }
}

公共BOOL IsInRole(字符串角色)
{
返回Array.BinarySearch(_role,角色)> = 0?真假;
}

公共BOOL IsInAllRoles(PARAMS字符串[]的角色)
{
的foreach(在角色串searchrole)
{
如果( Array.BinarySearch(_role,searchrole)小于0)
返回false;
}
返回真;
}

公共BOOL IsInAnyRoles(PARAMS字符串[]的角色)
{
的foreach(在角色串searchrole)
{
如果( Array.BinarySearch(_role,searchrole)0)
返回真;
}
返回FALSE;
}
}
}


解决方案

我会换用Thread.CurrentPrincipal中一类叫然后提取接口。这种方法可以让我通过我的虚拟实现,作为一个依赖



另一种方法是准备这样的静态类:

 公共静态类ApplicationPrincipal 
{
私有静态Func键<&的IPrincipal GT; _current =()=> Thread.CurrentPrincipal中;


公共静态的IPrincipal当前
{
{返回_current(); }
}

公共静态无效SwitchCurrentPrincipal(Func键<&的IPrincipal GT;主)
{
_current =本金;
}

}



然后,你必须使用ApplicationPrincipal。当前在你的仓库,而不是直接调用。在测试中,你将能够通过调用ApplicationPrincipal.SwitchCurrentPrincipal切换默认的逻辑(()=> myPrincipal)。



编辑:



我会改变:

 公共BOOL IsUserAuthenticated 
{
{返回((UserPrincipal)校长).Identity.IsAuthenticated; }
}

使用:

 公共BOOL IsUserAuthenticated 
{
{返回ApplicationPrincipal.Current.Identity.IsAuthenticated; }
}



然后在安排的测试,我会改变默认的IPrincipal与部分:

  VAR principalMock =新UserPrincipal(isAuthenticated:真); 

ApplicationPrincipal.SwitchCurrentPrincipal(()=> principalMock);



我假设你能以某种方式重载IsAuthenticated的UserPrincipal对象的值。


I am trying to perform a unit test of an n-tier application, service layer, repository layer and web api controllers. My repositories are checking the Thread.CurrentPrincipal object to get the current user. This is where I have a problem, when I create the implementation class that inherits from IPrincipal it does allow me to set the IsUserAuthenticated. Is there a way to simulate this for my unit tests. I would like to set the Thread.CurrentPrincipal to my implementation object. How would I simulate a user in this way?

In my RepositoryBase code, I call the following to determine if user is authenticated:

public bool IsUserAuthenticated
{
   get { return ((UserPrincipal)Principal).Identity.IsAuthenticated; }
}

The actual test looks something like:
Contract.Requires<UserAccessException>(IsUserAuthenticated, "Illegal Access.");




I am pulling IsUserAuthenticated from the UserPrincipal below:

namespace HeyLetsTrain.Toolkit.Helper.Authentication
{
public class UserPrincipal : IPrincipal
{
    IIdentity _identity;
    string[] _role;
    string _emailAddress;


    public UserPrincipal(string name, string[] role)
    {
        if (role != null)
        {
            _role = new string[role.Length];
            _role.CopyTo(role, 0);
            Array.Sort(_role);
        }
        _identity = new GenericIdentity(name);
    }

    public IIdentity Identity
    {
        get { return _identity; }
    }

    public string EmailAddress
    {
        get { return _emailAddress; }
        set { this._emailAddress = value; }
    }

    public bool IsInRole(string role)
    {
        return Array.BinarySearch(_role, role) >= 0 ? true : false;
    }

    public bool IsInAllRoles( params string [] roles )
    {
      foreach (string searchrole in roles )
      {
        if (Array.BinarySearch(_role, searchrole) < 0 )
          return false;
      }
      return true;
    }

    public bool IsInAnyRoles( params string [] roles )
    {
      foreach (string searchrole in roles )
      {
        if (Array.BinarySearch(_role, searchrole ) > 0 )
          return true;
      }
      return false;
    }
}
}
解决方案

I would wrap Thread.CurrentPrincipal call with a class and then extract the interface. This approach would allow me to pass my dummy implementation as a dependency.

Another approach is to prepare static class like this:

public static class ApplicationPrincipal
{
  private static Func<IPrincipal> _current = () => Thread.CurrentPrincipal;


  public static IPrincipal Current
  {
      get { return _current(); }
  }

  public static void SwitchCurrentPrincipal(Func<IPrincipal> principal)
  {
      _current = principal;
  }

}

Then you have to use ApplicationPrincipal.Current in your repositories instead of direct call. In your tests you will be able to switch default logic by calling ApplicationPrincipal.SwitchCurrentPrincipal(() => myPrincipal).

Edit:

I would change:

public bool IsUserAuthenticated
{
   get { return ((UserPrincipal)Principal).Identity.IsAuthenticated; }
}

With:

public bool IsUserAuthenticated
{
   get { return ApplicationPrincipal.Current.Identity.IsAuthenticated; }
}

And then in arrange section of the test I would change default IPrincipal with:

var principalMock = new UserPrincipal(isAuthenticated: true);

ApplicationPrincipal.SwitchCurrentPrincipal(() => principalMock);

I assume you can somehow overload the value of IsAuthenticated in UserPrincipal object.

这篇关于单元测试,如何设置和Thread.CurrentPrincipal中IsAuthenticated的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 23:21