在单元测试中为ApiController设置User属性

JTe*_*ech 24 c# iprincipal asp.net-web-api

我对ApiController的单元测试使用一些帮助器方法来实例化控制器:

public static ResourcesController SetupResourcesController(HttpRequestMessage request, IResourceMetadataRepository repo, IUnitOfWorkService unitOfWorkService)
{
    var config = new HttpConfiguration();
    var defaultRoute = config.Routes.MapHttpRoute(RouteNames.DefaultApi , "api/{controller}/{id}");
    var routeData = new HttpRouteData(defaultRoute, new HttpRouteValueDictionary { { "controller", "resources" } });

    var resourcesController = new ResourcesController(repo, unitOfWorkService)
    {
        ControllerContext = new HttpControllerContext(config, routeData, request),
        Request = request
    };
    resourcesController.Request.Properties.Add(HttpPropertyKeys.HttpRouteDataKey, routeData);
    resourcesController.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config;

    // Compilation fail: The Property 'System.Web.Http.ApiController.User' has no setter.
    resourcesController.User = myStubUserPrincipal;

    return resourcesController;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:如何设置控制器的用户属性?

我试过了:

request.Properties.Add("MS_UserPrincipal", myStubUserPrincipal);
Run Code Online (Sandbox Code Playgroud)

但这也不起作用(resourcesController.User属性保持为null).

Pab*_*aro 37

设置Thread.CurrentPrincipal,然后将User自动初始化控制器中的属性.

对于看到此答案的人,但不知道如何设置CurrentPrincipal.: 此代码是从MSDN中提取的.

Thread.CurrentPrincipal = new GenericPrincipal
(
   new GenericIdentity("Bob", "Passport"),
   new[] {"managers", "executives"}
);
Run Code Online (Sandbox Code Playgroud)

  • 对于那些看到这个答案但却不知道如何设置CurrentPrincipal的人.此代码从MSDN中提取.Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("Bob","Passport"),new [] {"managers","executive"}); http://msdn.microsoft.com/en-us/library/system.threading.thread.currentprincipal.aspx如果需要,请将此添加到您的答案中. (3认同)
  • 你也可以直接在控制器上设置它:`resourcesController.RequestContext.Principal = new ...` (3认同)

Sta*_*lav 10

一个清洁的方法是嘲笑远IPrincipalHttpRequestContext,例如使用起订量:

var userMock = new Mock<IPrincipal>();
userMock.Setup(p => p.IsInRole("admin")).Returns(true);
userMock.SetupGet(p => p.Identity.Name).Returns("tester");
userMock.SetupGet(p => p.Identity.IsAuthenticated).Returns(true);

var requestContext = new Mock<HttpRequestContext>();
requestContext.Setup(x => x.Principal).Returns(userMock.Object);

var controller = new ControllerToTest()
{
    RequestContext = requestContext.Object,
    Request = new HttpRequestMessage(),
    Configuration = new HttpConfiguration()
};
Run Code Online (Sandbox Code Playgroud)