Visual Studio 在测试方法中模拟声明的同一性

oalqel3c  于 2023-03-24  发布在  其他
关注(0)|答案(1)|浏览(125)

我有一个控制器方法,它调用其他一些代码并传递用户信息。

[HttpPost]
  [Route("")]
    public async Task<IHttpActionResult> MyRecords([FromBody] myBody body,
        CancellationToken cancellationToken)
    {
        try
        {
           //some logic;
           var user = GetUser();
           var ready = new CreateRecords(new Execute("Test"), new Contracts.Data.User(user.Id, user.Name));
        }
        catch (Exception e)
        {
            _log.Error("Request failed", e);
            return base.InternalServerError(e);
        }
    }

    public static UserInfo GetUser()
    {
        if (!(Thread.CurrentPrincipal?.Identity is ClaimsIdentity identity))
            return null;

        var name = identity.Claims.FirstOrDefault(claim => claim.Type == ClaimTypes.Name)?.Value ?? "";
        var userId = identity.Claims.FirstOrDefault(claim => claim.Type == ClaimTypes.NameIdentifier)?.Value;
        return null == userId ? null : new UserInfo(int.Parse(userId), name);
    }

现在我写单元测试agains控制器的方法和位失去了如何传递用户信息,因为我没有任何构造函数,接受该信息,所以如何模拟这个信息在单元测试?
这就是我的控制器的构造函数的样子

private readonly ILog _log;

    public MyTestController(ILog log)
    {
        _log = log;
    }

这是我的测试方法

[Test]
    public async Task TestMethod()
    {
        // Arrange
        
        var controller = new MyTestController(new Mock<ILog>().Object);
    }
qhhrdooz

qhhrdooz1#

您的GetUser()读取静态属性Thread.CurrentPrincipal,因此如果您想操作该静态方法返回的内容,则还必须编写该属性。
幸运的是,它是可公开写入的,所以你可以这样做:

Thread.CurrentPrincipal = new ClaimsPrincipal(new ClaimsIdentity(
    new[] { 
        new Claim(ClaimTypes.Name, "FooName"), 
        new Claim(ClaimTypes.NameIdentifier, "42") 
    }
));

然后进行剩下的测试。
另请参阅:How can I safely set the user principal in a custom WebAPI HttpMessageHandler?

相关问题