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
Post a Comment