I am trying to Unit Test that a controller action returns the correct view. I am using .NET Core, Moq, and NUnit.
I want test the default ManageController,
The Constructor is below,
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; } And am trying to Unit Test the following Index Action, and Assert that it returns the correct ViewModel when successful. (And will add other paths that return different ViewModels in future)
[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); } After many attempts, my closest solution is as follows,
I have mocked, UserManager, and Setup the GetUserASync method with a ClaimsPrincipal with the Id "1". I have also set the HttpContext to use the same ClaimsPrincipal and passed that the the controller.
As the Action is async, I was forced to make the test method async. Currently the test fails due to the async Task that is returned being null. I can't see if the rest of the test passes as I can't get past this error.
[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); }