Unit Testing with a UserManager


.net coreAre you working on a project where you would like to add unit testing. Would you like to unit test controllers that depend upon a UserManager having been added to your dependency injection. Well I did and it took a bit of working out.

Setup

The first thing i did was create a new Asp .net core web application including asp .net identity. To keep things basic i followed this Introduction to Identity on ASP.NET Core this gave me a totally basic application web application with a single controller. I decided to add a new controller

[Route("api/[controller]")]
    [ApiController]
    public class CheckUserController : ControllerBase
    {
        private readonly UserManager _userManager;

        public CheckUserController(UserManager userManager)
        {
            _userManager = userManager;
        }

        public async Task GetUser(string userId)
        {
            var user = await _userManager.FindByIdAsync(userId);
            return user;
        }
}}

The above controller has a single method GetUser which accepts a string being the user id and returns the user. Ideally something like this would be behind an authorize attribute but for testing purposes I left it out.

Test application Setup

I created a new project using xunit and included the test web project as a dependency. You will also need the following NugetPackages

  • Microsoft.AspNetCore.Http.Abstractions
  • Microsoft.Extensions.Logging.Abstractions
  • Microsoft.Extensions.Options
  • Moq
  • xunit
  • xunit.runner.visualstudio

Unit Test

The first thing we do is create a mock IUserStore to hold our users. We use the setup extension to add users to the store. Once that is done we can create new UserManager object passing it the store of users. This user manager can then be used to call the constructor on the controller which will then prepare it for our call to the actual action on the controller.

[Fact]
        public async Task Test1()
        {
            // Arrange
            var store = new Mock>();
            store.Setup(x => x.FindByIdAsync("123", CancellationToken.None))
                .ReturnsAsync(new IdentityUser()
                {
                    UserName = "test@email.com",
                    Id = "123"
                });

            var mgr = new UserManager(store.Object, null, null, null, null, null, null, null, null);

            var controller = new CheckUserController(mgr);

            // Act
            var result = await controller.GetUser("123");

            // Assert
            Assert.NotNull(result);
            Assert.Equal("123", result.Id);
        }

Conclusion

In order to unit test a controller you must instantiate the controller with all of the objects it requires to run. Normally these objects are passed in by dependency injection when creating unit tests we must create these ourselves by creating mock objects. This enables our unit tests to run on exactly the data we want to check, it also means that we dont need to have a database when unit testing we can mock the data that would normally have been returned by a database. You can find my question relating to this on Stack overflow How to mock UserManager


About Linda Lawton

My name is Linda Lawton I have more than 20 years experience working as an application developer and a database expert. I have also been working with Google APIs since 2012 and I have been contributing to the Google .Net client library since 2013. In 2013 I became a a Google Developer Experts for Google Analytics.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.