2017-07-03 49 views
0

我正在爲ASP.NET 5.x項目使用asp.net樣板。我正在嘗試爲這個項目創建測試用例,它將調用現有的測試數據庫(一個數據庫用於主機,另一數據庫用於租戶)。我到此爲止了到:ASP.NET Boilerplate,真實數據庫的測試用例

  1. TestBase類的構造函數我打電話,將工作一樣MultiTenantMigrateExecuter.Run()將種子數據用於測試主機數據庫和測試租戶數據庫的方法(我將使用主機數據庫和一個Tenant數據庫進行測試)。種子將與真實分貝相同,只是測試數據庫的名稱不同。
  2. 也從TestBase類構造函數我從主機數據庫中獲取TenantId。
  3. 接下來我試圖從租戶數據庫 這樣得到任何種子用戶:var user= UsingDbContext(context => context.Users.FirstOrDefault(t => t.UserName== "johndoe"));但當然這將調用HostDb而不是TenantDb。

我發現了一個方法,使該TenantDb呼叫通過在using語句這樣包裝的代碼,avoidint的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

播放,同時與代碼後,我找到了答案,我的問題... 在TestBase I類創建了一個新的靜態屬性:

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 }); 
     } 
    } 
} 

創建後,你可以在你的測試用例中使用它。