简体   繁体   English

在测试中为WPF应用程序设置CurrentPrincipal

[英]Setting CurrentPrincipal for a WPF application from within a test

we have a WPF application that uses CurrentPrincipal to handle security. 我们有一个使用CurrentPrincipal来处理安全性的WPF应用程序。 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: 问题是,在测试的初始化中,我们创建了应用程序的新实例,但是我们不知道如何在此应用程序上设置CurrentPrincipal:

 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? 有谁知道如何从应用程序外部为WPF应用程序设置CurrentPrincipal?

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. 这里有许多不同的策略可供选择,但是许多采用的一种策略是模拟必要的IPrincipal和IIdentity对象,以模拟当前线程的主体和身份。 I will show how this can be done using the Mocking framework Moq next: 接下来,我将展示如何使用Mocking框架Moq做到这一点:

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. 请注意,可以直接设置Thread.CurrentPrincipal,但是在编写单元测试时,强烈建议通常使用模拟框架或隔离框架。 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. 当然,这里必须选择模拟是正确的选择,还是Moq是要使用的正确框架。 There are several alternatives when it comes to mocking. 关于模拟,有几种选择。 Moq is really nice mocking framework, but cannot mock static methods for example. Moq是一个非常好的模拟框架,但是不能模拟静态方法。 Other mocking frameworks offer more functionality than Moq and so on. 其他模拟框架比Moq等提供了更多功能。

A quickstart for Moq is available here if this seems like a possible route to follow: 如果这是一条可行的路线,请在此处提供Moq的快速入门:

http://code.google.com/p/moq/wiki/QuickStart 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). (请注意,我是一名独立开发人员,我之所以建议Moq不是因为我喜欢,而是因为我之前在与您类似的场景中使用了该模拟框架)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM