Search code examples
asp.net-mvc-5nunitnsubstitute

How do I mock the ApplicationUserManager for unit testing using nsubstitute and nunit


I am having a problem in mocking out the ApplicationUserManager class using nsubstitute and nunit for testing my action method. Here is the way am mocking the class.

var _userManager = Substitute.For<ApplicationUserManager>();

In my system under test, am injecting the class using constructor injection. When I run the test, i get this error message.

Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: JobHub.Web.Identity.ApplicationUserManager.
Could not find a parameterless constructor.

My question is how do I properly mock this class using NSubstitue as am using the SetPhoneNumberAsync()method of the class.

EDIT By the way, here is the piece of code that am trying to test

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(UserProfileView model)
{
    if (ModelState.IsValid)
    {
        var userId = User.Identity.GetUserId(); 

        var profile = model.MapToProfile(userId);

        if (CommonHelper.IsNumerics(model.PhoneNo))
        {
            await _userManager.SetPhoneNumberAsync(userId, model.PhoneNo);
        }

        if (model.ProfileImage != null)
        {
            profile.ProfileImageUrl = await _imageService.SaveImage(model.ProfileImage);
        }

        _profileService.AddProfile(profile);
        _unitofWork.SaveChanges();

        //Redirect to the next page (i.e: setup experiences)
        return RedirectToAction("Skills", "Setup");
    }
    return View("UserProfile", model);
}

Solution

  • This error occurs when substituting for a concrete class, but the required constructor arguments have not been provided. If a MyClass constructor takes two arguments, it can be substituted like this:

    var sub = Substitute.For<MyClass>(firstArg, secondArg);
    

    Please keep in mind that NSubstitute can not work with non-virtual methods, and when substituting for classes (rather than interfaces) there are some occasions when real code can be executed.

    This is explained a bit further in Creating a substitute.