gpt4 book ai didi

c# - 在常规 mvc Controller (不是 web api Controller )中使用身份的单元测试方法

转载 作者:太空狗 更新时间:2023-10-29 21:12:50 24 4
gpt4 key购买 nike

我在常规 mvc Controller 中有一个方法,它检查用户的身份以查看应将用户定向到哪个页面。但是,针对此方法构建单元测试会引发“未设置对象引用”错误,因为当该方法作为测试的一部分运行时,User 始终为 null。

public ActionResult Index()
{
if (User.Identity.IsAuthenticated)
{
if (User.IsInRole("Administrator"))
{
return RedirectToAction("Console");
}

ViewBag.StatusMessage = "You are logged in but do not have sufficient permissions.";
}
else
{
ViewBag.StatusMessage = "Please log in";
}

return View();
}

我尝试了 Writing Unit Test for methods that use User.Identity.Name in ASP.NET Web API 提供的各种解决方案.这些通常在单元测试主体内使用类似以下内容:

var identity = new GenericIdentity("UserName");
Thread.CurrentPrincipal = new GenericPrincipal(identity, null);
var controller = new FooController();

如果 Controller 是 ApiController(即 WebApi 项目的 Controller ),则此方法工作正常,但它似乎不适用于常规 Web mvc Controller 。用户对象保持为空。如何解决?

最佳答案

link您发布的与 WebAPI 相关的内容,可以理解,对 ApiController 进行单元测试并访问用户对象非常容易。

这与 ASP.NET MVC 有一些不同,因为它并不简单。如果我们走上使用手动/手写模拟的道路,我们可能会发现自己在 mock 整个宇宙,而不是编写有值(value)的测试。

我将这两种方法都包括在内,以便您理解。我也使用问题中发布的链接中的相同示例。

使用手动手写模拟

//System Under Test - i.e to test User
public class SutController : Controller
{
public string Get() {
return User.Identity.Name;
}
}

public class TestableControllerContext : ControllerContext {
public TestableHttpContext TestableHttpContext { get; set; }
}

public class TestableHttpContext : HttpContextBase {
public override IPrincipal User { get; set; }
}

[TestMethod]
public void IndexNoneMoq()
{
var identity = new GenericIdentity("tugberk");
var controller = new SutController();

var controllerContext = new TestableControllerContext();
var principal = new GenericPrincipal(identity, null);
var testableHttpContext = new TestableHttpContext
{
User = principal
};

controllerContext.HttpContext = testableHttpContext;
controller.ControllerContext = controllerContext;

Assert.AreEqual(controller.Get(), identity.Name);
}

使用模拟/隔离框架,即 Moq

[TestMethod]
public void IndexMoq()
{
var identity = new GenericIdentity("tugberk");
var controller = new SutController();

var controllerContext = new Mock<ControllerContext>();
var principal = new Mock<IPrincipal>();
principal.Setup(p => p.IsInRole("Administrator")).Returns(true);
principal.SetupGet(x => x.Identity.Name).Returns("tugberk");
controllerContext.SetupGet(x => x.HttpContext.User).Returns(principal.Object);
controller.ControllerContext = controllerContext.Object;

Assert.AreEqual(controller.Get(), identity.Name);
}

请注意,我认为下一版本的 ASP.NET 对 WebAPI 和 MVC (AFAIK) 使用相同的底层组件,因此这可能是使用用户实例的单向单元测试目标 Controller 。

关于c# - 在常规 mvc Controller (不是 web api Controller )中使用身份的单元测试方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24337497/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com