我正在为ASP.NET 5.x的项目使用asp.net样板文件。我正在尝试为这个项目创建测试用例,它将调用现有的测试数据库(一个数据库用于主机,另一个数据库用于租户)。到目前为止我的步骤是:
TestBase
类构造函数中,我调用的方法与MultiTenantMigrateExecuter.Run()
一样,它将为Test Host数据库和Test Tenant数据库播种数据(我将使用主机db和单个租户数据库进行测试)。播种将与真实数据库相同,只是测试数据库的名称不同。TestBase
类构造函数我从主机数据库获取TenantId。var user= UsingDbContext(context => context.Users.FirstOrDefault(t => t.UserName== "johndoe"));
但当然这将调用HostDb而不是TenantDb。我找到了一种方法来调用TenantDb,方法是将代码包装在这样的using语句中,避免context
和usint存储库,以便能够从TenantDb获取我需要的用户:
using (this.AbpSession.Use(tenant.Id, null))
{
// get the TenantDb.User here by using the User repository
}
...然后在我写的每个测试用例中都这样:
using (this.AbpSession.Use(AbpSession.TenantId, AbpSession.UserId))
{
// make calls to the Tenant database here by using Tenant repository
}
但这不是最干净的解决方案,它有其局限性。
问题是:在我的情况下是否有更好的方法,在TestBase
类中设置上下文以默认调用Tenant数据库而不是Host数据库?
我也试过这个,但它没有用......
protected T UsingTenantDbContext<T>(Func<TestAppDbContext, T> func)
{
T result;
using (this.AbpSession.Use(AbpSession.TenantId, AbpSession.UserId))
{
using (var context = LocalIocManager.Resolve<TestAppDbContext>())
{
context.DisableAllFilters();
result = func(context);
context.SaveChanges();
}
}
return result;
}
答案 0 :(得分:0)
用代码玩了一会后,我找到了问题的答案...... 在TestBase类中,我创建了一个新的静态属性:
internal static MyAppDbContext tenantContext;
静态,因为这个类会被多次继承,但是tenantContext只能设置一次。
接下来我创建了以下方法:
protected void CreateTenantDbContext()
{
if (tenantContext == null)
{
using (var context = LocalIocManager.Resolve<MyAppDbContext>())
{
// AbpSession.TenantId is set in a previous method.
// Usin the host context, get the Connection String for the necessary tenant
var encryptedDbConnString = context.Tenants.FirstOrDefault(x => x.Id == AbpSession.TenantId)?.ConnectionString;
// Decrypt the string
var decryptedDbConnString = SimpleStringCipher.Instance.Decrypt(encryptedDbConnString);
// Create the context for the tenant db and assign it to the static property tenantContext
tenantContext = LocalIocManager.Resolve<MyAppDbContext>(new { nameOrConnectionString = decryptedDbConnString });
}
}
}
创建后,您可以在测试用例中使用它。