如何模拟ApplicationUserManager使用nsubstitute和nunit进行单元测试
问题描述:
我在使用nsubstitute和nunit模拟ApplicationUserManager
类来测试我的动作方法时遇到问题。这是嘲笑课堂的方式。如何模拟ApplicationUserManager使用nsubstitute和nunit进行单元测试
var _userManager = Substitute.For<ApplicationUserManager>();
在我的系统中,我正在使用构造函数注入注入类。当我运行测试时,我收到此错误消息。
Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: JobHub.Web.Identity.ApplicationUserManager.
Could not find a parameterless constructor.
我的问题是如何正确使用嘲弄作为NSubstitue现在用的是类的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中有进一步的解释。
是的,但我怎么能创建一个真正的类,不执行真正的代码,而是只调用传递给它的回调的替代品。我尝试过使用[when-do回调](http://nsubstitute.github.io/help/callbacks),尽管它调用了回调函数,但它仍然调用真正的代码。如果没有,可以用moq来实现吗? – Cizaphil 2015-01-22 09:45:09
非虚拟成员中的构造函数代码和代码将始终运行。我相信Moq,FakeItEasy和RhinoMocks都有类似的限制,尽管这些项目值得检查和/或向SO发布一般性的.net模拟问题。确保真正的代码不会运行的最好方法是使用一个接口(因为它们没有真正的代码)。如果您无法编辑原始类,则有一种选择是使用适配器模式使原始类符合接口。 – 2015-01-22 11:10:05
非常感谢,我终于解决了这个问题,并通过使用Moq扩展方法嘲笑'IUserStore'和'IUserPhoneNumberStore ',并返回所需的'Task '来通过测试。虽然看起来有点乱,但它的工作原理。 –
Cizaphil
2015-01-22 12:39:58