ASP MVC单元测试GetUserId()
本文关键字:GetUserId 单元测试 MVC ASP | 更新日期: 2023-09-27 18:24:12
我有一个控制器,在那里我调用一个userId:
var userId = User.Identity.GetUserId();
这使得我的单元测试失败,因为User为null。我曾尝试使用此方法在测试方法中设置一个用户,但当测试运行时,user在控制器中仍然为null。
var context = new Mock<HttpContextBase>();
var mockIdentity = new Mock<IIdentity>();
context.SetupGet(x => x.User.Identity).Returns(mockIdentity.Object);
mockIdentity.Setup(u => u.Name).Returns("test_userName");
关于我做错了什么,有什么线索吗?
HttpContextBase.User
的类型为IPrincipal
,您没有对其进行嘲讽。这就是为什么在测试中访问它时它会返回null。你可以模仿它如下
var controllerContext = new Mock<ControllerContext>();
var principal = new Moq.Mock<IPrincipal>();
principal.Setup(p => p.IsInRole("Administrator")).Returns(true);
principal.SetupGet(x => x.Identity.Name).Returns(userName);
controllerContext.SetupGet(x => x.HttpContext.User).Returns(principal.Object);
controller.ControllerContext = controllerContext.Object;
以下是此代码的参考
好吧,根据这篇文章,你可以这样做:
public class MyController: Controller
{
public Func<string> GetUserId; //For testing
public MyController()
{
GetUserId = () => User.Identity.GetUserId();
}
//controller actions
}
然后,您不需要在需要用户时缩放User.Identity.GetUserId()
,只需调用GetUserId()
并在测试中模拟出用户id:
controller = new MyController()
{
GetUserId = () => "IdOfYourChoosing"
};
您正在模拟HttpContextBase,但没有将其传递给控制器。试试这个模式:
类别:
public MyClass
{
private readonly HttpContextBase _contextBase;
public MyClass(HttpContextBase contextBase)
{
this._contextBase = contextBase;
}
public void Process()
{
var userId = _contextBase.User.Identity;
}
}
测试:
[Test]
public void MyClass_Test_SO()
{
// arrange
var context = new Mock<HttpContextBase>();
var mockIdentity = new Mock<IIdentity>();
context.SetupGet(x => x.User.Identity).Returns(mockIdentity.Object);
mockIdentity.Setup(u => u.Name).Returns("test_userName");
var sut = new MyClass(context.Object);
// act
sut.Process();
// assert
// ... whatever
}