【问题标题】:Unit Test - How to set controller user to Generic Principal object单元测试 - 如何将控制器用户设置为通用主体对象
【发布时间】:2017-10-10 12:34:43
【问题描述】:

更新完整解决方案:

我要测试的 WebApi 控制器方法:

using Microsoft.AspNet.Identity;
using System.Web.Http;


[Authorize]
public class GigsController : ApiController
{
    private readonly IUnitOfWork _unitOfWork;

    public GigsController(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }        

    [HttpDelete]
    public IHttpActionResult Cancel(int id)
    {
        var userId = User.Identity.GetUserId();
        var gig = _unitOfWork.Gigs.GetGigWithAttendees(id);

        if (gig.IsCanceled)
            return NotFound();

        if (gig.ArtistId != userId)
            return Unauthorized();

        gig.Cancel();

        _unitOfWork.Complete();

        return Ok();
    }
}

单元测试类:

[TestClass]
public class GigsControllerTests
{
    private GigsController _controller;
    public GigsControllerTests()
    {
        var identity = new GenericIdentity("user1@domain.com");
        identity.AddClaim(
            new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "user1@domain.com"));
        identity.AddClaim(
            new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", "1"));

        var principal = new GenericPrincipal(identity, null);

        var mockUoW = new Mock<IUnitOfWork>();
        _controller = new GigsController(mockUoW.Object);
        _controller.User = principal;
    }

我收到以下错误:

错误 CS0200 属性或索引器“ApiController.User”不能 分配给 -- 它是只读的

https://i.stack.imgur.com/YDQJS.png

【问题讨论】:

  • 这是不正确的。 ApiController.User 不是只读的。所以你需要提供一个minimal reproducible example 可以用来重现问题。这样我们就可以更好地评估问题的真正原因。
  • 您好 Nkosi,我已经更新了完整的解决方案,它仍然显示 ApiController.User 是只读的
  • 同时显示GigsController 声明。
  • 刚刚更新的伙伴 :)
  • 我使用提供的代码尝试重现您的问题,但正如预期的那样,代码编译,允许将值分配给 ApiController.User 属性。除非您在示例中显示的内容有其他内容,否则您显示的错误将无法重现。

标签: c# unit-testing asp.net-web-api tdd asp.net-apicontroller


【解决方案1】:

您可以通过ControllerContext分配它

var user = new ClaimsPrincipal();
var context = new ControllerContext
{
    HttpContext = new DefaultHttpContext
    {
        User = user
    }
};

controllerUnderTest.ControllerContext = context;

【讨论】:

    【解决方案2】:

    我在学习 Moshi 的教程时遇到了同样的问题,这让我困扰了好几个小时才最终解决这个问题。

    最终,为我解决这个问题的方法是更改​​我的 using 语句:

    使用 GigHub.Controllers;

    使用 GigHub.Controllers.Api;

    您的 GigsController _controller 指向的是控制器本身,而不是 ApiController。我有点希望 Moshi 将“Api”放在他的 API 类的名称中,这样您就可以知道您是在查看纯控制器还是控制器的 API 版本,而无需检查名称空间或转到对象的定义。

    你说得对,Controller 类的 User 属性确实只有一个 Get。

    public abstract class Controller : ControllerBase, IActionFilter, 
    IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, 
    IResultFilter, IAsyncController, IController, IAsyncManagerContainer
    {
       public IPrincipal User { get; }
    }
    

    ApiController 类的 User 属性同时具有 Get 和 Set。

    public abstract class ApiController : IHttpController, IDisposable
    {
        public IPrincipal User { get; set; }
    }
    

    希望这也是您的问题并帮助您解决问题!

    干杯!

    【讨论】:

      【解决方案3】:

      改为设置执行线程的CurrentPrincipal

      Thread.CurrentPrincipal = principal;
      

      【讨论】:

      • 不是一回事。
      【解决方案4】:

      当我试图在控制器而不是 controller.api 中模拟用户时,我遇到了这篇文章......并且很挣扎。 无论如何,这样做的方法是用模拟对象覆盖控制器中的 ControllerContext ,并设置模拟对象以返回您希望模拟的用户。

      var user = CreateLoggedInUser(targetUserID);
      
      mockControllerContext = new Mock<ControllerContext>();
      
      mockControllerContext.Setup(o => o.HttpContext.User).Returns(user);
      
      myCaseController.ControllerContext = mockControllerContext.Object;
      

      private ClaimsPrincipal CreateLoggedInUser(int userID)
          {
              GenericIdentity myIdentity = new GenericIdentity("apiTestUser");
              myIdentity.AddClaims(new List<Claim> {
                  new Claim(ClaimTypes.Sid, userID.ToString()),
      
              });
              return new ClaimsPrincipal(myIdentity);
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-07
        • 2017-07-20
        • 2012-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-24
        相关资源
        最近更新 更多