簡體   English   中英

創建用於單元測試的存儲庫

[英]Creating repositories for Unit Testing

我已經用C#,MVC,實體框架,LINQ等編寫了一個Web應用程序,現在我想為整個項目追溯創建單元測試。

我知道,為了編寫有效的單元測試,我需要為模型創建存儲庫,以便可以對它們進行模擬,因此實體框架將對數據庫產生任何影響。

我有3個主要模型; 類別,密碼,UserPassword。

類別包含類別和密碼。 密碼包含UserPasswords(鏈接到用戶帳戶)。 因此,我用基本方法創建了3個存儲庫,例如; 創建,刪除,更新等...

但是,查看此LINQ查詢:

var selectedCategoryItem = DatabaseContext.Categories
                .Where(c => c.CategoryId == ParentCategoryId)
                .Include(c => c.SubCategories)
                .Include(c => c.Passwords)
                .Include(c => c.Passwords.Select(p => p.Creator))
                .ToList()
                .Select(c => new Category()
                {

                SubCategories = c.SubCategories
                            .Where(sub => !sub.Deleted)
                            .OrderBy(sub => sub.CategoryOrder)
                            .ToList(),                          //make sure only undeleted subcategories are returned

                Passwords = c.Passwords
                            .Where(pass => !pass.Deleted
                            && (
                            (UserPasswordList.Any(up => up.PasswordId == pass.PasswordId && up.Id == UserId))
                            || (userIsAdmin && ApplicationSettings.Default.AdminsHaveAccessToAllPasswords)
                            || pass.Creator_Id == UserId
                            )
                            )   //make sure only undeleted passwords - that the current user has acccess to - are returned
                            .OrderBy(pass => pass.PasswordOrder)
                            .ToList(),

                CategoryId = c.CategoryId,
                CategoryName = c.CategoryName,
                Category_ParentID = c.Category_ParentID,
                CategoryOrder = c.CategoryOrder,
                Parent_Category = c.Parent_Category,
                Deleted = c.Deleted
                })
                .SingleOrDefault();

如果存儲庫只有基本方法,如保存,更新,刪除,插入,FindById等...,我應該如何將查詢分解到存儲庫中? 那里還有很多業務邏輯,例如過濾用戶可以訪問的密碼,該密碼應該放在哪里?

我讀了一些有關返回IQueryable對象的內容,以便可以在服務層中更改LINQ查詢...看起來如何?

如果您要編寫單元測試,則所有LINQ to Entities都應位於接口后面,

例如

public interface ICategoryRepository {
    List<Category> GetCategoriesForParentId(int id);
}

然后是一個實現該方法並包含LINQ和過濾邏輯的類。

現在,在需要訪問它的客戶端類中,通過構造函數傳遞ICategoryRepository (推薦)。 對於單元測試,將模擬的存儲庫傳遞到構造函數中,該構造函數將返回預定義的結果集。

為了測試實際的存儲庫篩選/轉換邏輯,我發現最好的方法是使用SQLite或SQL CE,並進行集成測試,以加載處於已知狀態的預定義數據庫(從保存的副本中加載) ,或在每個測試中重新創建它)並進行集成測試,將存儲庫類指向SQLite或SQL CE數據庫,而不是您的真實類,以便始終處於已知狀態,運行查詢並檢查結果集。

編輯:

將存儲庫所需的詳細信息傳遞到方法中,例如:

List<Category> GetCategoriesForParentIdAnduser(int id, int passwordId, int userId);

或者,由於用戶可能遍布整個網站,因此您可以通過

public interface IUserConfig {
     int PasswordId{ get; set; }
     int UserId { get; set;}
}


// Constructor for CategoryRepository : ICategoryRepository 
public CategoryRepository(DbContext context, IUserConfig)  
{
   ....
}

然后

public List<Category> GetCategoriesForParentId(int id){
     return _context.Categories
                .....
                Passwords = c.Passwords.Where(
                            .....
                            (UserPasswordList.Any(up => up.PasswordId == _userConfig.PasswordId 
                                                     && up.Id == _userConfig.UserId))                            
                .....
}

EDIT2:剛注意到.SingleOrDefault() ,而不是返回List<Category> ,而不是返回Category

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM