c# - Creating repositories for Unit Testing -
i've written web application in c#, mvc, entity-frame, linq etc... , want retroactively create unit tests whole project.
i understand in order write effective unit tests, need create repositories models, can mocked, , entity framework hits on database.
i have 3 main models; category, password, userpassword.
categories contain categories , passwords. , passwords contain userpasswords (which link user accounts). i've created 3 repositories basic methods such as; create, delete, update etc...
however, looking @ linq query:
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 undeleted subcategories 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 undeleted passwords - current user has acccess - 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();
if repositories have basic methods save, update, delete, insert, findbyid etc.... how should break query repositories? there's lot of business logic in there such filtering passwords user has access to, should sit?
i read returning iqueryable objects, linq queries can changed in service layer... how look?
if want write unit tests, of linq entities, should behind interface,
e.g.
public interface icategoryrepository { list<category> getcategoriesforparentid(int id); }
then class implements method , contains linq , filtering logic.
now in client classes need access it, pass in icategoryrepository
via constructor (recommended). , unit testing, pass in mocked repository constructor returns pre-defined result set.
for testing actual repository filtering/transforming logic, found best, use sqlite or sql ce, , have integration test, loads pre-defined database, in known state (either saved copy, or re-creating each test) , have integration tests, pointing repository class @ sqlite or sql ce database, rather real 1 in known state, run query, , check result set.
edit:
either pass in details needed repository method, e.g.:
list<category> getcategoriesforparentidanduser(int id, int passwordid, int userid);
or, user across site, pass
public interface iuserconfig { int passwordid{ get; set; } int userid { get; set;} } // constructor categoryrepository : icategoryrepository public categoryrepository(dbcontext context, iuserconfig) { .... }
then
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: noticed .singleordefault()
, rather returning list<category>
return category
.
Comments
Post a Comment