I have the following code:
var clientId = this.UserManager.FindById(this.User.Identity.GetUserId()).ClientId;
这是我的应用程序中一个控制器的一部分。现在我正在编写单元测试,需要通过此功能以测试控制器的实际属性。
问题在于它会抛出空引用异常,因为 UserManager.FindById
返回 null
。如果我可以模拟它,则它将具有一个名为ClientId的属性,我就能避免异常。
我尝试了什么? 首先是对UserManager本身进行模拟:
var fakeUserManager = new Mock<ApplicationUserManager>();
fakeUserManager.Setup(x => x.FindById(It.IsAny<string>()))
.Returns(user);
但是当我尝试将controller.UserManager设置为它时:
controller.UserManager = fakeUserManager.Object;
Visual Studio提示UserManager无法在此上下文中使用,因为set访问器不可访问。
我决定使用UserManager创建用户,但create方法再次导致了空引用异常。
这是如何设置ApplicationUserManager的:
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
解决方案:
感谢@mason的回答,我成功解决了这个问题。我将把解决方案发布为编辑版本,因为解决方案中有些细节并没有在问题和答案中提到。 首先,如@mason所建议的那样,我将UserManager属性的setter设置为public。
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
set
{
_userManager = value;
}
}
其次,这是不同的部分。我能够通过模拟IUserStore
,创建一个新的ApplicationUserManager
并将用户传递给它:
var store = new Mock<IUserStore<User>>(MockBehavior.Strict);
store.As<IUserStore<User>>()
.Setup(x => x.FindByIdAsync(It.IsAny<string>()))
.ReturnsAsync(user);
var manager = new ApplicationUserManager(store.Object);
然后,我只需设置控制器的UserManager:
controller.UserManager = manager;
备注:
user
变量帮助我向控制器传递具有ClientId的用户。
UserManager
属性最初是如何设置的?通过构造函数吗? - mason