如何使用 nsubstitute 和 nunit 模拟 ApplicationUserManager 进行单元测试

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

我在使用 nsubstitute 和 nunit 模拟 ApplicationUserManager class 来测试我的操作方法时遇到问题。这是我嘲笑 class.

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

在我的测试系统中,正在使用构造函数注入注入 class。当我 运行 测试时,我收到此错误消息。

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

我的问题是如何使用 NSubstitue 正确地模拟此 class,就像我使用 class 的 SetPhoneNumberAsync() 方法一样。

编辑 顺便说一句,这是我要测试的一段代码

[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);
}

此错误发生在 substituting for a concrete class 时,但尚未提供所需的构造函数参数。如果 MyClass 构造函数有两个参数,它可以这样替换:

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

请记住,NSubstitute 不能使用非虚拟方法,并且当替换 类(而不是接口)时,在某些情况下可以执行真实代码。

这在 Creating a substitute 中有进一步解释。