这里有许多不同的策略可供选择,但许多人采用的一种策略是模拟模拟当前线程的主体和身份所必需的 IPrincipal 和 IIdentity 对象。接下来,我将展示如何使用 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);
}
}
}
注意 Thread.CurrentPrincipal 可以直接设置,但是在编写单元测试时,一般强烈建议使用模拟框架或隔离框架。通常我们不是在测试安全代码,而是在代码中为视图模型或类似类编写单元测试,因此我们抽象、隔离或模拟这些依赖关系,例如线程上的当前主体,这样我们就可以专注于我们真正想要的东西为我们的代码逻辑编写单元测试。
当然,必须选择 mocking 是正确的选择,还是 Moq 是正确的使用框架。在模拟方面有几种选择。Moq 是一个非常好的模拟框架,但不能模拟例如静态方法。其他模拟框架提供比 Moq 等更多的功能。
如果这似乎是一条可行的路线,可在此处获得最小起订量的快速入门:
http://code.google.com/p/moq/wiki/QuickStart
(请注意,我是一名独立开发人员,我建议 Moq 的原因不是因为我喜欢,而是因为我之前已经使用过这个模拟框架来处理与你在这里类似的场景)。