asp.net - How to test functions returning data from a database -
say have function:
public list<car> getfourwheeldrives() { return datacontext.cars.where(c => c.isfourwheeldrive == true).tolist(); }
firstly it's kind of obvious i'm trying here. suggestions on how i'm doing this? improvements?
so want unit test this. unit test? unit test isn't suppose touch database right? functional test?
so write test
[test] public void getfourwheeldrives_noparameters_returnalistofonlycarsthatarefourwheeldrives { assert.greater(datacontext.cars.where(c => c.isfourwheeldrive == false).tolist().count, 0); var cars = getfourwheeldrives(); assert.greater(cars.count, 0); assert.areequal(cars.count, cars.where(c => c.isfourwheeldrive == true).tolist().count); }
so first assert i'm making sure cars aren't 4wd exist in database otherwise wouldn't valid test.
second assert i'm making sure @ least 1 returned.
third assert i'm making sure cars returned in fact 4wd.
i know isn't test because i'm using same logic in test function i'm testing. way can think of this.
can tell me how test properly?
thanks!
well, according 1 school of tdd, that's should do; write tests incorporate logic you're developing, refactor logic out of test , production class.
however, not call doing unit test, because unit tests definition should not touch external resources databases, file systems, , other "integration points". "integration tests", , though they're useful, should try write side-effect-free tests can prove code works designed.
look @ you're testing. basically, want ensure function queries linq datasource cars four-wheel drive, , not other type. assume, minute, linq2sql knows full how turn linq statement sql query against db. don't need test that; need test correct query made code against datasource.
to this, should implement mock. mock testing object stands in external resource, , can told expect calls methods , behave in way. here, should mock datasource object. in order able this, class containing getfourwheeldrives() must given object outside scope; if new()s 1 up, you're "tightly coupled" linq2sql provider , cannot write true unit test (you still write integration test if can point linq2sql @ testing db). given can pass in datasource used, should give mock expects have cars property accessed, , returns array of cars objects iqueryable. can define array, meaning have control on data query executing against, , can test query returned objects should return.
using rhino.mocks, code might this:
[test] public void getfourwheeldrives_noparameters_returnalistofonlycarsthatarefourwheeldrives { var datasource = mockrepository.generatemock<idatacontext>(); var carsarray = new []{new car{isfourwheeldrive = false}, new car{isfourwheeldrive = true}}; datasource.expect(ds=>ds.cars).return(carsarray.asqueryable()).repeat.atleastonce(); var objecttotest = new testobject(datasource); var cars = objecttotest.getfourwheeldrives(); assert.areequal(cararray.count(c=>c.isfourwheeldrive), cars.count); foreach(var car in cars) assert.istrue(car.isfourwheeldrive); }
this test proves given set of cars of arbitrary size, function return only, , exactly, cars 4wd, without needing real db so. unit tests should in cases class you're testing has dependencies on external code.
Comments
Post a Comment