linq - Comparing lambda expressions in C# with the help of ToString -


i'm trying assert 2 linq expressions in test. i'm using moq , on callback capture expression invoked inside method under test.

expression<func<role, bool>> actualexpression = null; rolerepositorymock.setup(t => t.search(it.isany<expression<func<role, bool>>>()))             .callback((expression<func<role, bool>> exp) =>                 {                     actualexpression = exp;                 })             .returns(new list<role> { new role { name = "site1_code_role1", description = "descr" }, new role { name = "site1_code" } }); 

i compare next way:

var sitecode = "site1"; var namepattern = "role1"; expression<func<role, bool>> expectedexpression =                      t => (string.isnullorempty(sitecode)                           || t.name.startswith(sitecode + "_")                            || t.name == sitecode)                            && t.name.contains(namepattern); assert.areequal(expectedexpression.tostring(), actualexpression.tostring()); 

the above assert fails. expected expression string equal to:

t => (((isnullorempty(value(bl.tests.rolesservicetests+<>c__displayclass6).sitecode) orelse t.name.startswith((value(bl.tests.rolesservicetests+<>c__displayclass6).sitecode + "_"))) orelse (t.name == value(bl.tests.rolesservicetests+<>c__displayclass6).sitecode)) andalso t.name.contains(value(bl.tests.rolesservicetests+<>c__displayclass6).namepattern)) 

and actual expression equal to:

t => (((isnullorempty(value(bl.services.rolesservice+<>c__displayclass3).site) orelse t.name.startswith((value(bl.services.rolesservice+<>c__displayclass3).site + "_"))) orelse (t.name == value(bl.services.rolesservice+<>c__displayclass3).site)) andalso t.name.contains(value(bl.services.rolesservice+<>c__displayclass3).pattern)) 

the differences in:

  • c_displayclass6 , c_displayclass3
  • bl.services.rolesservice , bl.tests.rolesservicetests (namespace different)

could explain or send me in right direction on why , how solve it? maybe absolutely wrong way try , compare these via tostring()? alternatives?

it better write tests validate externally observable behavior of piece of code without being coupled implementation details. converting expression string, coupling test not exact expression, implementation of tostring method, subject change in future .net versions.

a better approach assert on output state. looks want verify linq expression passed repository filter out right role collection. since can capture expression via callback, why not write tests against expression?

assuming role poco, should trivial write tests invoke expression different collections of role inputs , assert correct output produced. if expression complex may need many inputs, this:

var roles = new list<role> {     new role { name = sitecode+"_role1"  },     new role { name = sitecode+"_role22"  },     new role { name = sitecode+"_role1324"  }, };  assert.areequal(2, roles.where(actualexpression.compile()).count()); //test number of roles returned expected 

better still test @ interface of client code, without test having knowledge of how repository queried.


Comments

Popular posts from this blog

asp.net mvc 3 - Using mvc3, I need to add a username/password to the sql connection string at runtime -

kineticjs - draw multiple lines and delete individual line -

thumbnails - jQuery image rotate on hover -