繁体   English   中英

在 ClaimsPrincipal 类上模拟扩展方法以在 HttpContext.User 中使用

[英]Mock an extension method on the ClaimsPrincipal class for use within HttpContext.User

扩展不能被 Moq 等框架模拟,因为它们是静态方法。

我的 ClaimsPrincipal 类有一个扩展方法,该方法在我的应用程序中广泛使用并且无法更改。 扩展方法称为GetUserSerial()

我希望能够以某种方式模拟这个扩展方法,以便我可以在我的单元测试中使用它,因为扩展方法本身在各种 ASP.NET Core 控制器中使用,因此我需要能够将它的输出模拟为正确测试控制器。

我正在尝试通过执行以下操作来模拟ControllerContext

private Mock<ControllerContext> GetMockControllerContext(Mock<ClaimsPrincipal> mockClaimsPrincipal)
        {
            if (mockClaimsPrincipal == null)
            {
                mockClaimsPrincipal = new Mock<ClaimsPrincipal>();
                mockClaimsPrincipal.Setup(x => x.GetSerialNo()).Returns("serial");
            }

            var contextMock = new Mock<HttpContext>();
            contextMock.SetupGet(ctx => ctx.User).Returns(mockClaimsPrincipal.Object);

            var controllerContextMock = new Mock<ControllerContext>();
            controllerContextMock.SetupGet(con => con.HttpContext).Returns(contextMock.Object);
            return controllerContextMock;
        }
public static string GetSerialNo(this ClaimsPrincipal claimsPrincipal)
        {
            return claimsPrincipal?.Claims?.FirstOrDefault(c => c.Type == "SerialNo")?.Value;
        }

然而,这显然会产生运行时错误,告诉我扩展方法不能被模拟。

这里的主要问题是扩展方法正在控制器内部使用,我无法更改它的输出。

有没有办法解决这个问题,以便我可以指定GetSerialNo方法的输出并在我的ControllerContext提供它?

不需要模拟。 创建具有所需声明的主体实例

string expectedSerial = "serial";
var claims = new List<Claim> {
    new Claim("SerialNo", expectedSerial),
};
var principal = new ClaimsPrincipal(new ClaimsIdentity(claims));

//...

这样,当扩展被调用时,它将按预期运行。

如果修改现有身份,则只需添加声明

//... principal already exists

string expectedSerial = "serial";
Claim claim = new Claim("SerialNo", expectedSerial);
(principal.Identity as ClaimsIdentity).AddClaim(claim);

//...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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