gpt4 book ai didi

c# - 带有 UserManager 的 ASP.NET 5 单元测试 Controller

转载 作者:太空狗 更新时间:2023-10-29 22:30:21 26 4
gpt4 key购买 nike

我开始使用 ASP.NET 5 (vNext),现在我正在尝试对使用 UserManager 来注册和登录用户的 Controller 进行单元测试。

我正在使用 xUnitmoq.netcore

在我的单元测试中我有:

var mockStore = new Mock<IUserStore<ApplicationUser>>(MockBehavior.Strict).As<IUserPasswordStore<ApplicationUser>>();

mockStore.Setup(x => x.CreateAsync(It.IsAny<ApplicationUser>(), CancellationToken.None)).Returns(Task.FromResult(new IdentityResult()));

var userManager = new UserManager<ApplicationUser>(mockStore.Object, null, null, null, null, null, null, null, null, null);

Controller 中的代码:

var result = await _securityManager.CreateAsync(user, model.Password);

但是,当我运行单元测试时,调用 CreateAsync 时出现空异常。

我不明白为什么我不能用 ApplicationUser 和字符串参数模拟 CreateAsync 方法,我必须用 CancellationToken 模拟它。

这是我第一个使用 ASP.NET 5 的项目,我之前使用的是 ASP.NET 4.6,所以现在很多东西都不同了。

而且,您认为我应该已经在 ASP.NET 5 中开发一个重要的项目,还是应该等待并为 ASP.NET 4.6 开发它?

最佳答案

在尝试了很多事情之后,我想出了一个可行的解决方案。

用户管理器

我创建了一个 FakeUserManager 类,它继承了 UserManager 并覆盖了 CreateAsync 方法。

public class FakeUserManager : UserManager<ApplicationUser>
{
public FakeUserManager()
: base(new Mock<IUserStore<ApplicationUser>>().Object,
new Mock<IOptions<IdentityOptions>>().Object,
new Mock<IPasswordHasher<ApplicationUser>>().Object,
new IUserValidator<ApplicationUser>[0],
new IPasswordValidator<ApplicationUser>[0],
new Mock<ILookupNormalizer>().Object,
new Mock<IdentityErrorDescriber>().Object,
new Mock<IServiceProvider>().Object,
new Mock<ILogger<UserManager<ApplicationUser>>>().Object,
new Mock<IHttpContextAccessor>().Object)
{ }

public override Task<IdentityResult> CreateAsync(ApplicationUser user, string password)
{
return Task.FromResult(IdentityResult.Success);
}
}

然后我将一个新的 FakeUserManager 实例传递给 AccountController 构造函数,它工作正常。


登录管理器

对于那些可能需要模拟 SignInManager 的人,我通过以下方式进行了模拟:

我创建了一个 FakeSignInManager 类,它继承了 SignInManager 并覆盖了我需要的方法。

public class FakeSignInManager : SignInManager<ApplicationUser>
{
public FakeSignInManager(IHttpContextAccessor contextAccessor)
: base(new FakeUserManager(),
contextAccessor,
new Mock<IUserClaimsPrincipalFactory<ApplicationUser>>().Object,
new Mock<IOptions<IdentityOptions>>().Object,
new Mock<ILogger<SignInManager<ApplicationUser>>>().Object)
{
}

public override Task SignInAsync(ApplicationUser user, bool isPersistent, string authenticationMethod = null)
{
return Task.FromResult(0);
}

public override Task<SignInResult> PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure)
{
return Task.FromResult(SignInResult.Success);
}

public override Task SignOutAsync()
{
return Task.FromResult(0);
}
}

并且由于 SignInManager 需要上下文访问器才能工作,所以我让 FakeSignInManager 在构造函数中接收它。

然后,在创建 SignInManager 的新实例之前,我通过以下方式准备了一个新的 HttpContextAccessor:

var context = new Mock<HttpContext>();
var contextAccessor = new Mock<IHttpContextAccessor>();
contextAccessor.Setup(x => x.HttpContext).Returns(context.Object);

然后创建新的 FakeSignInManager 实例:

new FakeSignInManager(contextAccessor.Object);

关于c# - 带有 UserManager 的 ASP.NET 5 单元测试 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35627568/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com