使用 GetUserASync (User) 的单元测试控制器



我正在尝试对控制器操作返回正确视图进行单元测试。我正在使用.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操作进行单元测试,并断言它在成功时返回正确的 ViewModel。(并且将来会添加返回不同视图模型的其他路径(

[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并通过了控制器。

由于操作是异步的,我被迫使测试方法异步。目前,由于返回的异步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);
}

设置模拟以返回任务,以便可以等待它并允许代码按预期流动

//...
var appUser = new ApplicationUser {
//...populate as needed
}
mockUserManager
.Setup(_ => _.GetUserAsync(user))
.ReturnsAsync(appUser); // Allows mocked member to be awaited and return desired type
//...

最新更新