Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何编写模拟不同用户的测试?_C#_Winforms_Mstest_Impersonation - Fatal编程技术网

C# 如何编写模拟不同用户的测试?

C# 如何编写模拟不同用户的测试?,c#,winforms,mstest,impersonation,C#,Winforms,Mstest,Impersonation,My Winforms应用程序根据当前进程中找到的组成员身份设置权限 我刚刚在MSTEST中做了一个单元测试 我想以其他用户的身份运行它,以便验证预期的行为 以下是我的拍摄目的: [TestMethod] public void SecuritySummaryTest1() { Impersonate(@"SomeDomain\AdminUser", password); var target = new DirectAgentsSecur

My Winforms应用程序根据当前进程中找到的组成员身份设置权限

我刚刚在MSTEST中做了一个单元测试

我想以其他用户的身份运行它,以便验证预期的行为

以下是我的拍摄目的:

    [TestMethod]
    public void SecuritySummaryTest1()
    {
        Impersonate(@"SomeDomain\AdminUser", password);
        var target = new DirectAgentsSecurityManager();
        string actual = target.SecuritySummary;
        Assert.AreEqual(
            @"Default=[no]AccountManagement=[no]MediaBuying=[no]AdSales=[no]Accounting=[no]Admin=[YES]", actual);
    }
    [TestMethod]
    public void SecuritySummaryTest2()
    {
        Impersonate(@"SomeDomain\AccountantUser", password);
        var target = new DirectAgentsSecurityManager();
        string actual = target.SecuritySummary;
        Assert.AreEqual(
            @"Default=[no]AccountManagement=[YES]MediaBuying=[no]AdSales=[no]Accounting=[YES]Admin=[NO]", actual);
    }

我没有包括ImpersonationException的实现,但这并不重要。它没有任何特殊功能。

您应该使用模拟对象来模拟处于不同状态的依赖对象。 有关模拟框架的示例,请参见:


您需要抽象出界面后面提供当前用户的位。并将该接口的模拟传递给被测试的类。

如果满足您的用例,您还可以直接设置当前主体:

System.Threading.Thread.CurrentPrincipal 
    = new WindowsPrincipal(new WindowsIdentity("testuser@contoso.com"));
根据本标准,在每次试验方法后,恢复主体。
请注意,如果与检查主体的web服务客户端一起使用,此方法将不起作用(对于本用例,Jim Bolla的解决方案工作得很好)

另一件要添加到Markus解决方案中的事情是,您可能还需要将HttpContext.Current.User设置为您正在为角色管理器的某些调用创建/模拟的Thread.CurrentPrincipal(例如:Roles.GetRolesForUser(Identity.Name))如果您使用该方法的无参数版本,则不需要这样做,但我有一个授权基础结构,需要传递用户名

使用模拟线程调用该方法签名。CurrentPrincipal将失败,原因是“仅当用户名参数与当前Windows标识中的用户名匹配时,才支持该方法”。如消息所示,WindowsTokenRoleProvider代码中存在针对“HttpContext.Current.Identity.Name”。如果它们不匹配,该方法将失败

下面是一个ApiController的示例代码,演示了一个操作的授权。我使用模拟进行单元和集成测试,这样我就可以在不同的AD角色下进行QA,以确保在部署之前安全工作正常

using System.Web

List<string> WhoIsAuthorized = new List<string>() {"ADGroup", "AdUser", "etc"};

public class MyController : ApiController {
    public MyController() {
     #if TEST 
        var myPrincipal = new WindowsPrincipal(new WindowsIdentity("testuser@contoso.com"));
        System.Threading.Thread.CurrentPrincipal = myPrincipal;
        HttpContext.Current.User = myPrincipal;
     #endif
    }
    public HttpResponseMessage MyAction() {
       var userRoles = Roles.GetRolesForUser(User.Identity.Name);
       bool isAuthorized = userRoles.Any(role => WhoIsAuthorized.Contains(role));
    }
}
使用System.Web
List WHOISUTHORIZED=新列表(){“ADGroup”、“AdUser”、“etc”};
公共类MyController:ApiController{
公共MyController(){
#如果测试
var myPrincipal=新的WindowsPrincipal(新的WindowsIdentity(“testuser@contoso.com"));
System.Threading.Thread.CurrentPrincipal=myPrincipal;
HttpContext.Current.User=myPrincipal;
#恩迪夫
}
公共HttpResponseMessage MyAction(){
var userRoles=Roles.GetRolesForUser(User.Identity.Name);
bool isAuthorized=userRoles.Any(role=>whoiauthorized.Contains(role));
}
}
希望这对其他人有帮助:)

使用

运行
Install Package SimpleImpersonation
安装nuget软件包

然后

var credentials = new UserCredentials(domain, username, password);
Impersonation.RunAsUser(credentials, LogonType.NewCredentials, () =>
{
    // Body of the unit test case. 
}); 

这是最简单、最优雅的解决方案。

即使我只测试一个类的属性?是不是存在对o/s安全子系统的依赖性,该子系统会覆盖?@LasseV.Karlsen。你能解释一下为什么模拟用户不会使其成为单元测试吗?如果我有一个方法,当用户这样做时,该方法会失败吗没有权限,我想对该场景进行单元测试,以实现代码覆盖率。您依赖于周围的环境,例如用户在域/服务器上,用户仍然处于活动状态,密码仍然正确等。相反,模拟检索权限的部分,以便测试中的代码可以通过不必模拟用户。任何依赖于正确设置的环境(即代码之外的内容)的测试都是集成创建测试,而不是单元测试。
var credentials = new UserCredentials(domain, username, password);
Impersonation.RunAsUser(credentials, LogonType.NewCredentials, () =>
{
    // Body of the unit test case. 
});