Unit Testing, how to set Thread.CurrentPrincipal and IsAuthenticated

北战南征 提交于 2019-12-06 10:25:20

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.

Do not set principal using Thread.CurrentPrincipal in unit tests. Set it using AppDomain.CurrentDomain.SetThreadPrincipal. This way every thread in unit tests will inherit your principal.

Drawback is that you can set principal using this method only once.

You might try using a object mocking framwork like NMock http://msdn.microsoft.com/en-us/magazine/cc163904.aspx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!