使用JWT Claims对.NET Core Web API控制器进行单元测试

6

我想测试一个控制器方法,该方法利用JWT声明获取客户端的用户名,如下所示:

[Authorize]
[Route("api/[controller]")]
public class ApprovalsController : Controller
{
  // POST api/approvals
    [HttpPost]
    public IActionResult Post([FromBody]ApprovalViewModel value)
    {
        // ...

        // Incoming approval VM converted here
        Approval newApproval = TinyMapper.Map<Approval>(value);

        // Values set server-side here.
        newApproval.Id = -1;
        newApproval.Created = DateTime.Now;

        // Claim queried here
        newApproval.CreatedBy = User.FindFirst(ClaimTypes.Name).Value; 

        // Submission to context
        _approvalRepo.Insert(newApproval);
        _approvalRepo.Update();

        // ...
    }

但是我一直在尝试使用Moq和XUnit对上述控制器进行单元测试,但运气实在不好。我搜索的许多问题都涉及直接设置控制器的ControllerBase.User属性,但在Aspnetcore.MVC(1.1.1)中,User已被设置为只读

那么我该怎么做呢?


2
@Nkosi 鉴于自我教育的目的,您能解释一下为什么这个问题与链接中的问题完全相同吗?两者有相似之处,但是Ilya的回答直接而简单,我认为这是值得称赞的。 - D Owrey
1个回答

9

Controller.User 只是 Controller.ControllerContext.HttpContext.User 的一个包装器。首先模拟任何上下文:

var controller = new HomeController();

var contextMock = new Mock<HttpContext>();
contextMock.Setup(x => x.User).Returns(new ClaimsPrincipal());

controller.ControllerContext.HttpContext = contextMock.Object;

Assert.NotNull(controller.User);

不知道是最近.NET的更改还是其他原因,但HttpContext现在需要一个HttpContextBase。只是想提一下。 - Thierry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接