c# - Proper way to avoid duplicating test data for unit tests -


lets have following unit test entity framework 6 using moq:

    public void save_employee_via_context()     {         var mockcontext = new mock<dcmdatacontext>();          var mockset = new mock<dbset<employee>>();          mockcontext.setup(m => m.employees).returns(mockset.object);          var service = new generalservice(mockcontext.object);          //test valid inputs          (int = 0; < testdata.validemployees.count; i++)         {             service.addemployee(testdata.validemployees[i]);             //veryfy inserted             assert.areequal(testdata.validemployees[i],mockset.object.find(testdata.validemployees[i].employeeid));         }         //ensure proper methods called each time.  implied happened if above          //assert methods passed, double checking never killed         mockset.verify(m => m.add(it.isany<employee>()), times.exactly(testdata.validemployees.count));         mockcontext.verify(m => m.savechanges(), times.exactly(testdata.validemployees.count));          //test invalid inputs          mockset = new mock<dbset<employee>>();         //invalidemployees dictionary<employee,type>, type type of exeption should eb thrown if          //you attempt add employee         foreach (var pair in testdata.invalidemployees)         {             try             {                 service.addemployee(pair.key);                 //addemployee *should* throw exception here here.. if not...                 assert.fail();             }             catch (exception ex)             {                 //was exception expecting catch?                 assert.equals(ex.gettype(), pair.value);             }         }         //ensure nothing new has been added (redundant, know, doesn't hurt)         mockset.verify(m => m.add(it.isany<employee>()), times.never);         mockcontext.verify(m => m.savechanges(), times.exactly(testdata.validemployees.count));      } 

testdata static class have holds lists each model type want test, along several test cases each, both valid , invalid inputs.

i created test because objects can large (employee, example, has around 15 properties), , such there wide array of test cases want run in order each test thorough. didn't want copy/paste, each array of test sample data every single method needs it, wanted store in static container.

i feel poses problem, however. instance, 1 of properties of employee position. know, job have. required property, , exception should thrown if position either null, or doesn't exist in database. means in order above test valid, i'm going need mock positions in there well. oh, each position has department attribute... needs set too...

do see going this? how can test code without full suite of test data test against? then, suppose i'll have write full suite of test data. did.

the problem is, put it? decided put in in testdata class.
this, however, presents set of problems. initialization biggest one, because feel have neuter test data in order make initialization remotely feasible. instance, of navigation properties going have null. how have validemployees each have list<clients>, , each client have assigned employee without, once again, hard duplicating each employee property of client, , in list<employee> each position going have. wouldn't nice have clients = {validclients[0],validclients[1] within validemployees , salesrepresentative = validemployees[0] within validclients?

i feel need navigation data. will

 assert.areequal  (      testdata.validemployees[i],      mockset.object.find(testdata.validemployees[i].employeeid  )  

still return true if validemployees doesn't have navigationdata in it? mean should find way of ensuring state?

anyway, these problems running into. setting unit tests wrong? how else supposed robust, independent, dry , accurate unit tests? missing here?

any appreciated, if means starting scratch different mindset. first project taking testing seriously, feel isn't going well. such, sorry wall of text. feel i'm not asking right question want go.

looking @ tests, appears service.addemployee :). can split validation logic, etc.

consider test (to lead design). uses fakedbset:

[test] public void should_add_any_valid_employees_and_save_them() {    //arrange    var validator = new mock<iemployeevalidator>();    validator.setup(v => v.validate(it.isany<employee>())).returns(true);     // ... setup context , dbset     var service = new myservice(validator.object, mockcontext.object)     var newdata = new list<employeedto>       {          new employeedto{id = 1},          new employeedto{id = 2}       }     // act    service.addemployees(newdata);     // assert    mockcontext.verify(c => c.savechanges(), times.once());    assert.true(fakedbset.count == newdata.count);    collectionassert.areequivalent( newdata.select(e=>e.id), mockdata.select(e=>e.id)); }  [test] public void should_not_add_any_invalid_employees() {    //arrange    var validator = new mock<iemployeevalidator>();    validator.setup(v => v.validate(it.isany<employee>())).returns(false);     // ... setup context , dbset     var service = new myservice(validator.object, mockcontext.object)     var newdata = new list<employeedto>       {          new employeedto{id = 1},          new employeedto{id = 2}       }     // act    service.addemployees(newdata);     // assert    mockcontext.verify(c => c.savechanges(), times.never());    assert.true(fakedbset.count == 0);    collectionassert.isempty( mockdata ); } 

you can throw in mix iemployeedtotoemployee mapper well, abstract part of functionality well.


Comments

Popular posts from this blog

c# - How Configure Devart dotConnect for SQLite Code First? -

java - Copying object fields -

c++ - Clear the memory after returning a vector in a function -