简体   繁体   中英

.net core mvc Mocking Identity and claims and test if user has claim

I'm trying to unit test my controller logic, it's a (.Net core 2 mvc App) I have a controller that returns details of an item if the user has specific claim, and I want to unit test that using XUnit.

Here is the controller:

public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var controlException = await _context.ControlException.FirstOrDefaultAsync(m => m.Id == id);

    if (controlException == null)
    {
        return NotFound();
    }
    if (User.HasClaim("control Claim", "control Claim"))
    {
            return View(controlException);
    }
    else
    {
        return RedirectToAction("AccessDenied", "Account");
    }

}

My Unit test code is : ( GetContextWithData() return InMemory test Database)

[Fact]
public async Task VerifyDetailsViewType()
{

    using (var context = GetContextWithData())
    using (var _controller = new ControlExceptionsController(context))
    {      
        var userStore = new Mock<IUserStore<ApplicationUser>>();

        var userManager = new UserManager<ApplicationUser>(
                         userStore.Object, null, null, null, null, null, null, null, null);

        var cp = new Mock<ClaimsPrincipal>();
        cp.Setup(m => m.HasClaim(It.IsAny<string>(), It.IsAny<string>()))
          .Returns(true);
        cp.Setup(m => m.Identity).Returns(identityMock.Object);

        _controller.ControllerContext.HttpContext = new DefaultHttpContext();
        _controller.ControllerContext.HttpContext.Request.Headers["Referer"] = "http://www.test.nl";

        var result = await _controller.Details(888);
        Assert.IsType<ViewResult>(result);
    }
}

My test failed because the result is " RedirectToAction " and not " ViewResult ".

I know because the user does't have the claim, so the question is how can I assign a claim to the user, in other words how can I mock the Identity and claims and manage this.

You need to assign the principal to the controller to allow the code to exercise to completion as desired.

You mock the principal but do not assign it to the controller in the test.

_controller.ControllerContext.HttpContext.User = cp.Object;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM