سؤال

we have a WPF application that uses CurrentPrincipal to handle security. This all works fine.

Now, from within a test project, we call view model operations. The problem is, that in the initialization of the test we create a new instance of the application but we don't know how to set the CurrentPrincipal on this application:

 private void TestInitialize()
 {
      var app = new App();
      // setting Thread.CurrentPrincipal doesn't set app thread it seems
 }

Anyone has an idea how to set the CurrentPrincipal for a WPF application from outside the application?

هل كانت مفيدة؟

المحلول

There are many different strategies to choose here, but one strategy which many adopt to is mocking the IPrincipal and IIdentity objects necessary to simulate principals and identities of the current thread. I will show how this can be done using the Mocking framework Moq next:

using System.Security.Principal;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace MockingIdentitySample.Test
{
 [TestClass]
 public class UnitTest1
{

    [TestInitialize]
    public void TestInitialize()
    {
        SetupMockedPrincipalAndIdentity(true, true, "John Doe"); 
    }

    private void SetupMockedPrincipalAndIdentity(bool autoSetPrincipal, bool isAuthenticated, string identityName)
    {
        var mockedPrincipal = new Mock<IPrincipal>();
        var mockedIdentity = new Mock<IIdentity>();
        mockedIdentity.Setup(m => m.Name).Returns(identityName);
        mockedIdentity.Setup(m => m.IsAuthenticated).Returns(isAuthenticated); 
        mockedPrincipal.Setup(p => p.Identity).Returns(mockedIdentity.Object);

        if (autoSetPrincipal)
         Thread.CurrentPrincipal = mockedPrincipal.Object;
    }

    [TestMethod]
    public void TestMethod1()
    {
        Assert.AreEqual(Thread.CurrentPrincipal.Identity.Name, "John Doe");
        Assert.IsTrue(Thread.CurrentPrincipal.Identity.IsAuthenticated); 
    }

   }
  }

Note that Thread.CurrentPrincipal can be set directly, but using a mocking framework or isolation framework in general is strongly suggested when writing unit tests. Often we are testing not the security code but are writing unit tests for view models or similar classes in our code and therefore we abstract, isolate or mock these dependencies such as the current principal on the thread away so we can focus on what we really want to write unit tests for - the logic of our code.

Of course, one must choose if mocking is the right choice here or if Moq is the correct framework to use. There are several alternatives when it comes to mocking. Moq is really nice mocking framework, but cannot mock static methods for example. Other mocking frameworks offer more functionality than Moq and so on.

A quickstart for Moq is available here if this seems like a possible route to follow:

http://code.google.com/p/moq/wiki/QuickStart

(Please note, I am an independent developer and the reason I suggested Moq was not because of my liking, but because I have used this mocking framework earlier for similar scenarios as yours here).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top