xUnit ClaimsPrincipal 模拟并传递到控制器用户为空

xUnit ClaimsPrincipal mock and passing into controller User is null

我一直在阅读试图解决这个问题的文章。根据本文 构建。我仍然从我的控制器中获取一个空用户,并且在控制器内的一个空用户对象上测试失败。

业务控制器

    [Route("api/[controller]")]
    [ApiController]
    public class BusinessController : ControllerBase
    {
        private readonly IGBusinessRepository businessRepository;
        private readonly IPersonRepository personRepository;
        private readonly IUserClaims userClaims;

        public BusinessController(IGBusinessRepository businessRepository,
                                    IPersonRepository personRepository,
                                    IUserClaims userClaims)
        {
            this.businessRepository = businessRepository;
            this.personRepository = personRepository;
            this.userClaims = userClaims;
        }

        // GET api/<BusinessController>/5
        [HttpGet("{id}")]
        [Authorize]
        public async Task<IActionResult> GetBusiness(Guid businessId)
        {
            var userGuid = userClaims.GetUserGuid(User.Claims);
            var ownerId = await personRepository.GetPersonIdByGUID(userGuid);
            var business = await businessRepository.GetBusinessById(businessId);
            if(business != null && business.OwnerId == businessId)
            {
                return Ok(business);
            }

            return BadRequest("Bad business id or your not the owner");            
        }

用户声明

    public class UserClaims : IUserClaims
    {
        public string GetUserGuid(IEnumerable<Claim> claims)
        {
            var claimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";
            var guidClaim = claims.Where(c => c.Type == claimType).Select(s => s.Value).SingleOrDefault();


            return guidClaim;
        }
    }

测试身份

    public class TestIdentity : ClaimsIdentity
    {
        public TestIdentity(params Claim[] claims) : base(claims)
        {

        }
    }

测试主体

    public class TestPrincipal : ClaimsPrincipal
    {
        public TestPrincipal(params Claim[] claims) : base(new TestIdentity(claims))
        {

        }
    }

业务控制器测试

    public class BusinessControllerTests
    {
        //Controller 
        private readonly Mock<IGBusinessRepository> mockBusinessRepository;
        private readonly Mock<IPersonRepository> mockPersonRepository;
        private readonly Mock<IUserClaims> mockUserClaims;
        private BusinessController controller;

        //Objects
        private Guid id = Guid.NewGuid(); 

        public BusinessControllerTests()
        {
            mockBusinessRepository = new Mock<IGBusinessRepository>();
            mockPersonRepository = new Mock<IPersonRepository>();
            mockUserClaims = new Mock<IUserClaims>();
            controller = new BusinessController(mockBusinessRepository.Object, mockPersonRepository.Object, mockUserClaims.Object);
        }

        [Fact]
        public async Task GetBussiness_NotBusinessOwner_ReturnsBadRequest()
        {
            //Arrange
            var userGuidString = Guid.NewGuid().ToString();
            var ownerId = Guid.NewGuid();
            var userClaim = new TestPrincipal(new Claim("name", "user@domain.com"));
            Thread.CurrentPrincipal = userClaim;
            
            //mockUserClaims.Setup(repo => repo.GetUserGuid(userClaim)).Returns(userGuidString);
            mockPersonRepository.Setup(repo => repo.GetPersonIdByGUID(userGuidString));
            mockBusinessRepository.Setup(repo => repo.GetBusinessById(id)).ReturnsAsync(business);

            //Act
            var result = await controller.GetBusiness(id);

            //Assert
            Assert.IsType<BadRequestResult>(result);
        }

        private GobiezBusiness business = new GobiezBusiness()
        {
            Id = new MongoDB.Bson.ObjectId(),
            BusinessId = Guid.NewGuid(),
            Name = "Test",
            Email = "Test@helpme.com",
            Address = "123 A street",
            State = "WA",
            ZipCode = "12345",
            PhoneNumber = "123-456-7890",
            OwnerId = Guid.NewGuid()
        };   
    }

控制器配置不正确,无法访问主体

// ... omitted for brevity

var userClaim = new TestPrincipal(new Claim("name", "user@domain.com"));
var httpContext = new DefaultHttpContext() {
    User = userClaim;
};

//Controller needs a controller context to access HttpContext
var controllerContext = new ControllerContext() {
    HttpContext = httpContext
};

//assign context to controller    
BusinessController controller = new BusinessController(
    mockBusinessRepository.Object, 
    mockPersonRepository.Object, 
    mockUserClaims.Object)
{
    ControllerContext = controllerContext
};

//Act
var result = await controller.GetBusiness(id);

// ... omitted for brevity

控制器也应该在正在执行的测试范围内创建。

被测题目中的这一行

//...

var userGuid = userClaims.GetUserGuid(User.Claims);

//...

现在应该return创建TestPrincipal安排在测试