c# - Using Moq and Xunit to test interfaces -


i new xunit , moq. trying understand both test frameworks , preparing unit test cases. using dependency injection inject interfaces.

i testing following interfaces

using system.collections.generic; using zeiss.imt.mccneo.settings.entities;  namespace zeiss.imt.mccneo.settings.data.interface {     public interface iprofilesrepository     {         ilist<profile> getallprofiles();         ilist<profile> getprofilesmatchinguserid(string userid);         ilist<profile> getprofilesforuseridwithsettingname(string userid, string settingname);     } } 

the implementation class

using system; using system.collections.generic; using zeiss.imt.mccneo.settings.data.interface; using zeiss.imt.mccneo.settings.entities; using system.linq; using zeiss.imt.mccneo.settings.data.singleton; using zeiss.imt.mccneo.settings.utilities;  namespace zeiss.imt.mccneo.settings.data.repository {     public class profilesrepository : iprofilesrepository     {         private iprofiledatarepository _profiledatarepository { get; set; }         public profilesrepository(iprofiledatarepository profiledatarepository)         {             _profiledatarepository = profiledatarepository;          }         public ilist<profile> getallprofiles()         {             return _profiledatarepository.get();         }         public ilist<profile> getprofilesmatchinguserid(string userid)         {             if (string.isnullorwhitespace(userid)) throw new argumentexception("user id cannot null");             return _profiledatarepository.get().where(puid => puid.userid.tolower() == userid.tolower()).tolist<profile>();         }         public ilist<profile> getprofilesforuseridwithsettingname(string userid, string settingname)         {             if (string.isnullorwhitespace(userid) || string.isnullorwhitespace(settingname)) throw new argumentexception("user id or settingname cannot null");             var profileswithsettings = _profiledatarepository.get().where(p => p.userid.tolower() == userid.tolower() & p.settings.any(s => s.name.tolower() == settingname.tolower()));             return profileswithsettings.tolist();         }     } } 

the data repository deals data loading , data saving file

using system; using system.collections.generic; using zeiss.imt.mccneo.settings.entities;  namespace zeiss.imt.mccneo.settings.data.singleton {     public interface iprofiledatarepository     {         list<profile> get();          list<profile> get(func<profile, bool> filter);         void save(list<profile> profilestosave);     } }  using system; using system.collections.generic; using zeiss.imt.mccneo.settings.entities; using zeiss.imt.mccneo.settings.utilities; using system.linq; namespace zeiss.imt.mccneo.settings.data.singleton {     public class profiledatarepository : iprofiledatarepository     {         private static list<profile> profiles;         public irepository _repository { get; set; }         public profiledatarepository(irepository repository)         {             _repository = repository;             if (profiles == null)             {                 profiles = repository.get<profile>();             }         }          public list<profile> get()         {             return profiles;         }          public list<profile> get(func<profile, bool> filter)         {             return profiles.where(filter).tolist();         }          public void save(list<profile> profilestosave)         {             profiles = profilestosave;             _repository.save<list<profile>>(profiles);         }     } } 

i trying mock profile entity , pass mocked interfaces. but, still lacking understanding on how mock interfaces , pass data entities.

entity class      namespace zeiss.imt.mccneo.settings.entities     {         public class profile         {             public string userid { get; set; }             public string username { get; set; }             public list<setting> settings { get; set; }         }     }  test class      using moq; using system; using system.collections.generic; using system.text; using zeiss.imt.mccneo.settings.data.interface; using zeiss.imt.mccneo.settings.data.singleton; using zeiss.imt.mccneo.settings.entities;  namespace zeiss.imt.mccneo.settings.tests {     public class profilesservicetests     {         private readonly mock<iprofiledatarepository> profiledataprovider;         private readonly mock<iprofilesrepository> profilesprovider;          public profilesservicetests()         {             profiledataprovider = new mock<iprofiledatarepository>();             profilesprovider = new mock<iprofilesrepository>();         }          public void getprofilesmatchinguserid_whenpassednull_return_exception()         {              list<setting> settings = new list<setting>() {                 new setting(){                     name = "refreshinterval",                      value = { },                      type = "string",                 encrypted = true,                 readonly = true,                 createdon = new datetime(),                 modifiedon = new datetime(),                 valid = true,                 enabled = true,                 description = "protocol archive view renwal interval in seconds. minimum value = 300 maximum value = 28800"                 }             };              profile profile = new profile()             {                 userid = "admin",                 username = "admin",                 settings = settings             };              list<profile> profiles = new list<profile>()             {                 profile             };              profiledataprovider.setup(x => x.get()).returns(profiles);             profilesprovider.setup(x => x.getprofilesmatchinguserid(null)).returns(new nullreferenceexception());          }     } } 

kindly, suggest.

it feels want test (or lot) in 1 class. keep in mind don't need make integration tests (yet).

first take @ profilesrepository.

we need

public class profilerepositorytests {     //this class reposible handle data iprofiledatarepository     private readonly profilesrepository _profilesrepository;     private readonly mock<iprofiledatarepository> _moqprofiledataprovider;      public profilerepositorytests()     {         _moqprofiledataprovider = new mock<iprofiledatarepository>();         _profilesrepository = new profilesrepository(_moqprofiledataprovider.object);     }      [fact]     public void get_succes_noprofiles()     {         _moqprofiledataprovider.setup(x => x.get()).returns(new list<profile>());          var profiles = _profilesrepository.getallprofiles();          assert.areequal(0, profiles.count);     }      [fact]     public void get_succes_allprofiles()     {         _moqprofiledataprovider.setup(x => x.get()).returns(new list<profile>         {             new profile {userid = "123"}         });          var profiles = _profilesrepository.getallprofiles();          assert.areequal(1, profiles.count);         assert.areequal("123", profiles.first().userid);         //test more properties     }      [fact]     public void getprofilesmatchinguserid_userid_null_throws_error()     {         exception ex = assert.throws<argumentexception>(() => _profilesrepository.getprofilesmatchinguserid(null));         } } 

this doesn't complete tests, gives idea how can continue. remember, seperate class/unit tests etc etc. each test should check 1 exception. remember, unit test tests 1 thing, 1 situation. if code throwing 2 different exceptions, it's can't doing under same conditions.

good luck!


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -