我正在尝试如何将单元测试添加到我的项目中。我认为最好从一个空白项目开始,从一开始就完成它,而不是把它添加到我的主要项目中。一旦我理解了这个过程,我就可以开始重构我的项目以添加测试。
web应用程序
因此,我创建了一个web应用程序,并在其中添加了默认的用户标识。
这让我开始看上去像这样
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}然后,我创建了一个简单的控制器,并在构造函数中传递了用户管理器。
[Route("api/[controller]")]
[ApiController]
public class SweetController : ControllerBase
{
private readonly UserManager<IdentityUser> _userManager;
public SweetController(UserManager<IdentityUser> userManager)
{
_userManager = userManager;
}
public async Task<int> NumberOfGummyBearsForUser(string userId)
{
var user = await _userManager.FindByIdAsync(userId);
var userHasASweetTooth = await _userManager.IsInRoleAsync(user, "SweetTooth");
if (userHasASweetTooth)
{
return 100;
}
else
{
return 1;
}
}
}单元测试
我一直试图做的第一件事就是嘲笑这个用户管理器,但它不起作用。
public void Test1()
{
// Arrange
var mockUser = new Mock<UserManager<IdentityUser>>();
var userManager = new UserManager(mockRepo.Object); <-- error here see image below
var controller = new SweetController(userManager.Object);
// Act
var result = await controller.NumberOfGummyBearsForUser("123");
// Assert
Assert.Equal(100, result);
}错误如下所示

我想我需要传递更多来创建这个用户管理器对象,但是我不知道我找到的所有教程都使用了ApplicationUser而不是IdentityUser,所以我对如何模拟这个对象感到困惑。
发布于 2019-03-29 08:15:07
你就这么做
// Arrange
var mockUser = new Mock<UserManager<IdentityUser>>();
var controller = new SweetController(mockUser.Object);你不需要
var userManager = new UserManager(mockRepo.Object); <-- error here see image below完全没有。mockUser已经是模拟的UserManager<T>,您可以通过mock.Object放置一个模拟实例。
当您模拟一个对象时,您不必用它的所有依赖项(即集成测试)实例化它,这就是模拟的意义(以及使方法返回所需的值并进行行为测试,以确保您的测试代码已经调用了带有模拟对象的特定参数的特定方法)。
当然,上面的代码本身是行不通的,因为您没有为FindByIdAsync和IsInRoleAsync设置任何测试条件/返回。你必须用
mockUser.Setup( userManager => userManager.FindByIdAsync(It.IsAny<string>()))
.ReturnsAsync(new IdentityUser { ... });
mockUser.Setup( userManager => userManager.IsInRoleAsync(It.IsAny<IdentityUser>(), "SweetTooth"))
.ReturnsAsync(true);然后,每当调用模拟时,它都会返回预定义用户和预定义结果。
发布于 2019-03-29 09:41:22
在曾的帮助下我完成了这个任务。一个完全工作的版本是
控制器
private readonly UserManager<IdentityUser> _userManager;
public SweetController(UserManager<IdentityUser> userManager)
{
_userManager = userManager;
}
public async Task<IdentityUser> GetUser(string userId)
{
var user = await _userManager.FindByIdAsync(userId);
return user;
}测试
[Fact]
public async Task Test1()
{
// Arrange
var store = new Mock<IUserStore<IdentityUser>>();
store.Setup(x => x.FindByIdAsync("123", CancellationToken.None))
.ReturnsAsync(new IdentityUser()
{
UserName = "test@email.com",
Id = "123"
});
var mgr = new UserManager<IdentityUser>(store.Object, null, null, null, null, null, null, null, null);
var controller = new SweetController(mgr);
// Act
var result = await controller.GetUser("123");
// Assert
Assert.NotNull(result);
Assert.Equal("123", result.Id);
}我删除了角色检查,只是为了让它尽可能基本地工作。
https://stackoverflow.com/questions/55412776
复制相似问题