Creating Mock Users in Asp.Net Core 3.1

I didn't mock UserManager<IdentityUser>
By: Steve Elliott

Before I get started, I wanted to first mention that I'm not guaranteeing this is the best approach, but it worked for me. I spent hours searching around and trying various approaches to figure this one out. Pretty much every example I ran across was showing how to mock up UserManager to return a single user (or was for previous versions of Asp.Net), but I wasn't finding anything that showed how to return a list of users that I could use in Asp.Net Core 3.1.

The common thing I kept finding was something like this:

var mockUserManager = new Mock<UserManager<IdentityUser>>();
mockUserManager.Setup(p => p.FindByIdAsync(It.IsAny<string>()))
    .ReturnsAsync(new IdentityUser { ... });

However, like I said, I needed it to return a list of users. I'm not going to go through all the different things I tried, because I'm sure some of them were laughable, but I was trying things like .Setup(p => p.Users).Returns... and that just wasn't working. 

My Solution

So, instead of mocking UserManager, what I decided to do was create an interface to get the list of users and just mock that interface. I should have thought of it sooner, but I kept trying to emulate the examples I was running across.

Interface

Here's an example interface to get the users:

using Microsoft.AspNetCore.Identity;
using System.Collections.Generic;
using System.Linq;

namespace MockUsersSampleApp.Interfaces
{
    public interface IManageUsers
    {
        List<IdentityUser> GetUsers();
    }

    public class ManageUsers : IManageUsers
    {
        private UserManager<IdentityUser> _userManager;
        public ManageUsers(UserManager<IdentityUser> userManager)
        {
            _userManager = userManager;
        }

        public List<IdentityUser> GetUsers() => _userManager.Users.ToList();
    }
}

After adding the interface to your application, don't forget to register it to the ConfigureServices method in the Startup.cs file.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    // Added this for the new interface
    services.AddScoped<IManageUsers, ManageUsers>();

    services.AddControllersWithViews();
    services.AddRazorPages();
}

Controller

Here's a basic example of using it in a controller which would return the users to a View with ViewData.

using Microsoft.AspNetCore.Mvc;
using MockUsersSampleApp.Interfaces;

namespace MockUsersSampleApp.Controllers
{
    public class HomeController : Controller
    {
        private readonly IManageUsers _manageUsers;

        public HomeController(IManageUsers manageUsers)
        {
            _manageUsers = manageUsers;
        }

        public IActionResult Index()
        {
            ViewData["userList"] = _manageUsers.GetUsers();
            return View();
        }
    }
}

Test

Now to test it, you just have to mock the interface

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using MockUsersSampleApp.Controllers;
using MockUsersSampleApp.Interfaces;
using Moq;
using Xunit;
using System.Collections.Generic;

namespace MockUsersSampleAppTests.Controllers
{
    public class HomeControllerTests
    {
        [Fact]
        public void HomeController_UsersList_ViewData_NotNullTest()
        {
            var mockManageUsers = new Mock<IManageUsers>();
            // Note: Pulling fake user data from private methods down below
            mockManageUsers.Setup(p => p.GetUsers()).Returns(GetUsersListTestData());
            var controller = new HomeController(mockManageUsers.Object);

            var result = controller.Index();
            var viewResult = Assert.IsType<ViewResult>(result);
            ViewDataDictionary viewData = viewResult.ViewData;
            Assert.NotNull(viewData["userList"]);
        }

        private List<IdentityUser> GetUsersListTestData()
        {
            var users = new List<IdentityUser>();
            users.Add(GetUserTestData());
            return users;
        }

        private IdentityUser GetUserTestData()
        {
            var user = new IdentityUser()
            {
                Id = "1234",
                UserName = "user@test.com"
            };
            return user;
        }
    }
}

In case you'd like to see more detailed examples of this code, I've uploaded a sample project to my GitHub account at: https://github.com/ElliottBrand/MockUserSampleApp

Hopefully you found this post helpful!