How to unit test NpgsqlDataReader extensions in C# -


i've been playing around ado.net extensions inspired postgresql pluralsight article rob conery.

i'm new unit testing , have been trying learn more writing tests around couple of extension methods i've written npgsqldatareader class.

an example of method i'm trying test:

    public static t toentity<t>(this npgsqldatareader reader) t : new()     {         var result = new t();         var properties = typeof(t).getproperties();          foreach (var prop in properties)         {             (var = 0; < reader.fieldcount; i++)             {                 if (reader.getname(i).replace("_", "").equals(prop.name, stringcomparison.invariantcultureignorecase))                 {                     var val = reader.getvalue(i) != dbnull.value ? reader.getvalue(i) : null;                     prop.setvalue(result, val);                 }             }         }          return result;     } 

i'm not sure how start mocking database connection, want test functionality of iterating on returned result object , mapping columns properties of generic entity class.

how go testing entity mapping, without accessing database?

thanks

update:

the code i've been using call extension above extension on npgsqlcommand class:

public static ienumerable<t> tolist<t>(this npgsqlcommand cmd) t : new() {     var results = new list<t>();     var reader = cmd.executereader();      while (reader.read())     {         results.add(reader.toentity<t>());     }      reader.close();     reader.dispose();      return results; } 

i'll using same techniques posted in answer below test method well.

first of all, method implementation not depend on concrete implementation of npgsqldatareader. can change signature to:

public static t toentity<t>(this idatareader reader) t : new() 

next, signature not logical. datareader used loop on result set , yields list of rows (with 0, 1 or more elements), not single result. more logical signature , implementation be:

public static ienumerable<t> toentity<t>(this idatareader reader) t : new() {     var properties = typeof(t).getproperties();      while (reader.read())     {         var result = new t();         foreach (var prop in properties)         {             (var = 0; < reader.fieldcount; i++)             {                 if (reader.getname(i).replace("_", "").equals(prop.name, stringcomparison.invariantcultureignorecase))                 {                     var val = reader.getvalue(i) != dbnull.value ? reader.getvalue(i) : null;                     prop.setvalue(result, val);                 }             }         }          yield return result;     } } 

now can provide fake implementation of idatareader. either can use mocking framework such nsubstitute, if you're new unit testing simpler way manually implement one. example, in gist (incomplete implementation) implemented idatareader on in-memory generic list (and extension method facilitate usage).

now can write test method this:

// note anonymous type here var expectedentity = new {my_property = "somevalue"}; var reader = new[] {     expectedentity }.asdatareader(); var entity = reader.toentity<myentity>().first(); assert.areequal("somevalue", entity.myproperty); 

finally, solution using reflection works, may end rather slow. keep in mind kind of code solved problem; have alook @ light-weight orm's such petapoco, dapper.net a.o.


Comments