在由 UseInMemoryDatabase() 创建的 IdentityDbContext 中使用身份管理器
Using Identity's Managers in IdentityDbContext that was created by UseInMemoryDatabase()
我制作此方法是为了使单元测试 DbContext
更容易。这种方法使我的 db
的 Context
在内存中。它之所以有效,是因为我用实体对其进行了测试(如 _context.Projects
、_context.Tests
等,在单元测试中,此方法有效):
public static TaskManagerDbContext Create()
{
var options = new DbContextOptionsBuilder<TaskManagerDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.EnableSensitiveDataLogging(true)
.Options;
var context = new TaskManagerDbContext(options);
context.SaveChanges();
return context;
}
我的 DbContextClass
看起来像这样:
public class TaskManagerDbContext : IdentityDbContext<ApplicationUser>, ITaskManagerDbContext
{
public TaskManagerDbContext(DbContextOptions<TaskManagerDbContext> options)
: base(options)
{
}
//db sets here
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfigurationsFromAssembly(typeof(TaskManagerDbContext).Assembly);
}
}
我的问题是,我们可以像 IdentityDbContext
那样在内存中生成 Identity 的 UserManager
、SignInManager
、RoleManager
吗?如何单元测试 Identity
诸如用户、内存中的角色之类的东西,就像我们可以用标准 Context
做的那样?如何在我测试它时在存储在内存中的假上下文中调用它 Managers
?
编辑:
基于 身份共享 context
这很明显。但是如何在通过 UseInMemoryDatabase()
方法创建的 IdentityDbContext
上使用 Managers
?
EDIT2:
我正在通过夹具注入 context
:
public class DatabaseFixture
{
public TaskManagerDbContext Context { get; private set; }
public DatabaseFixture()
{
this.Context = DatabaseContextFactory.Create();
}
}
[CollectionDefinition("DatabaseTestCollection")]
public class QueryCollection : ICollectionFixture<DatabaseFixture>
{
}
及其用法:
[Collection("DatabaseTestCollection")]
public class RegisterUserCommandTests
{
private readonly TaskManagerDbContext _context;
public RegisterUserCommandTests(DatabaseFixture fixture)
{
_context = fixture.Create();
}
//and usage of it in class:
var user = _context.Projects.Find(8);
}
我正在使用 Xunit
。
您需要创建一个服务集合,向其中注册所有内容,然后使用它来提取您需要的内容。
var services = new ServiceCollection();
services.AddDbContext<TaskManagerDbContext>(o =>
o.UseInMemoryDatabase(Guid.NewGuid()));
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<TaskManagerDbContext>();
var provider = services.BuildServiceProvider();
然后,您可以使用 provider
:
using (var scope = provider.CreateScope())
{
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();
}
我制作此方法是为了使单元测试 DbContext
更容易。这种方法使我的 db
的 Context
在内存中。它之所以有效,是因为我用实体对其进行了测试(如 _context.Projects
、_context.Tests
等,在单元测试中,此方法有效):
public static TaskManagerDbContext Create()
{
var options = new DbContextOptionsBuilder<TaskManagerDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.EnableSensitiveDataLogging(true)
.Options;
var context = new TaskManagerDbContext(options);
context.SaveChanges();
return context;
}
我的 DbContextClass
看起来像这样:
public class TaskManagerDbContext : IdentityDbContext<ApplicationUser>, ITaskManagerDbContext
{
public TaskManagerDbContext(DbContextOptions<TaskManagerDbContext> options)
: base(options)
{
}
//db sets here
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfigurationsFromAssembly(typeof(TaskManagerDbContext).Assembly);
}
}
我的问题是,我们可以像 IdentityDbContext
那样在内存中生成 Identity 的 UserManager
、SignInManager
、RoleManager
吗?如何单元测试 Identity
诸如用户、内存中的角色之类的东西,就像我们可以用标准 Context
做的那样?如何在我测试它时在存储在内存中的假上下文中调用它 Managers
?
编辑:
基于 context
这很明显。但是如何在通过 UseInMemoryDatabase()
方法创建的 IdentityDbContext
上使用 Managers
?
EDIT2:
我正在通过夹具注入 context
:
public class DatabaseFixture
{
public TaskManagerDbContext Context { get; private set; }
public DatabaseFixture()
{
this.Context = DatabaseContextFactory.Create();
}
}
[CollectionDefinition("DatabaseTestCollection")]
public class QueryCollection : ICollectionFixture<DatabaseFixture>
{
}
及其用法:
[Collection("DatabaseTestCollection")]
public class RegisterUserCommandTests
{
private readonly TaskManagerDbContext _context;
public RegisterUserCommandTests(DatabaseFixture fixture)
{
_context = fixture.Create();
}
//and usage of it in class:
var user = _context.Projects.Find(8);
}
我正在使用 Xunit
。
您需要创建一个服务集合,向其中注册所有内容,然后使用它来提取您需要的内容。
var services = new ServiceCollection();
services.AddDbContext<TaskManagerDbContext>(o =>
o.UseInMemoryDatabase(Guid.NewGuid()));
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<TaskManagerDbContext>();
var provider = services.BuildServiceProvider();
然后,您可以使用 provider
:
using (var scope = provider.CreateScope())
{
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();
}