使用 GetUserASync(用户)的单元测试控制器
Unit Testing Controller that uses GetUserASync (User)
我正在尝试对控制器操作 return 进行单元测试以确保视图正确。我正在使用 .NET Core、Moq 和 NUnit。
我想测试默认 ManageController
,
构造函数在下面,
public ManageController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ILogger<ManageController> logger,
UrlEncoder urlEncoder)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_logger = logger;
_urlEncoder = urlEncoder;
}
我正在尝试对以下 Index
操作进行单元测试,并在成功时断言它 return 是正确的 ViewModel。 (并且将来会添加 return 不同 ViewModels 的其他路径)
[HttpGet]
public async Task<IActionResult> Index()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
var model = new IndexViewModel
{
Username = user.UserName,
Email = user.Email,
PhoneNumber = user.PhoneNumber,
IsEmailConfirmed = user.EmailConfirmed,
StatusMessage = StatusMessage
};
return View(model);
}
经过多次尝试,我最接近的解决方案如下,
我已经嘲笑,UserManager
,并使用 ID 为“1”的 ClaimsPrincipal
设置 GetUserASync
方法。我还将 HttpContext
设置为使用相同的 ClaimsPrincipal
并将其传递给控制器。
由于 Action 是异步的,我被迫将测试方法设为异步。目前,由于 returned 的异步 Task
为 null,因此测试失败。我无法查看其余测试是否通过,因为我无法克服此错误。
[Test]
public async Task Index_UserExists_ReturnsViewAsync()
{
var mockUserStore = new Mock<IUserStore<ApplicationUser>>();
var mockUserManager = new Mock<UserManager<ApplicationUser>>(mockUserStore.Object, null, null, null, null, null, null, null, null);
var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.NameIdentifier, "1"),
}));
mockUserManager.Setup(x => x.GetUserAsync(user));
var controller = new ManageController(mockUserManager.Object, null, null, null, null)
{
ControllerContext = new ControllerContext()
{
HttpContext = new DefaultHttpContext() { User = user }
}
};
//Act
var result = await controller.Index();
//Assert
Assert.IsInstanceOf<ViewResult>(result);
}
将模拟设置为 return 任务,以便等待它并允许代码按预期流动
//...
var appUser = new ApplicationUser {
//...populate as needed
}
mockUserManager
.Setup(_ => _.GetUserAsync(user))
.ReturnsAsync(appUser); // Allows mocked member to be awaited and return desired type
//...
我正在尝试对控制器操作 return 进行单元测试以确保视图正确。我正在使用 .NET Core、Moq 和 NUnit。
我想测试默认 ManageController
,
构造函数在下面,
public ManageController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ILogger<ManageController> logger,
UrlEncoder urlEncoder)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_logger = logger;
_urlEncoder = urlEncoder;
}
我正在尝试对以下 Index
操作进行单元测试,并在成功时断言它 return 是正确的 ViewModel。 (并且将来会添加 return 不同 ViewModels 的其他路径)
[HttpGet]
public async Task<IActionResult> Index()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
var model = new IndexViewModel
{
Username = user.UserName,
Email = user.Email,
PhoneNumber = user.PhoneNumber,
IsEmailConfirmed = user.EmailConfirmed,
StatusMessage = StatusMessage
};
return View(model);
}
经过多次尝试,我最接近的解决方案如下,
我已经嘲笑,UserManager
,并使用 ID 为“1”的 ClaimsPrincipal
设置 GetUserASync
方法。我还将 HttpContext
设置为使用相同的 ClaimsPrincipal
并将其传递给控制器。
由于 Action 是异步的,我被迫将测试方法设为异步。目前,由于 returned 的异步 Task
为 null,因此测试失败。我无法查看其余测试是否通过,因为我无法克服此错误。
[Test]
public async Task Index_UserExists_ReturnsViewAsync()
{
var mockUserStore = new Mock<IUserStore<ApplicationUser>>();
var mockUserManager = new Mock<UserManager<ApplicationUser>>(mockUserStore.Object, null, null, null, null, null, null, null, null);
var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.NameIdentifier, "1"),
}));
mockUserManager.Setup(x => x.GetUserAsync(user));
var controller = new ManageController(mockUserManager.Object, null, null, null, null)
{
ControllerContext = new ControllerContext()
{
HttpContext = new DefaultHttpContext() { User = user }
}
};
//Act
var result = await controller.Index();
//Assert
Assert.IsInstanceOf<ViewResult>(result);
}
将模拟设置为 return 任务,以便等待它并允许代码按预期流动
//...
var appUser = new ApplicationUser {
//...populate as needed
}
mockUserManager
.Setup(_ => _.GetUserAsync(user))
.ReturnsAsync(appUser); // Allows mocked member to be awaited and return desired type
//...