entity framework - Why can't I create a callback for the List Find method in Moq? -
i created extension method lets me treat list dbset testing purposes (actually, found idea in question here on stack overflow, , it's been useful). coded follows:
public static dbset<t> asdbset<t>(this list<t> sourcelist) t : class { var queryable = sourcelist.asqueryable(); var mockdbset = new mock<dbset<t>>(); mockdbset.as<iqueryable<t>>().setup(m => m.provider).returns(queryable.provider); mockdbset.as<iqueryable<t>>().setup(m => m.expression).returns(queryable.expression); mockdbset.as<iqueryable<t>>().setup(m => m.elementtype).returns(queryable.elementtype); mockdbset.as<iqueryable<t>>().setup(m => m.getenumerator()).returns(queryable.getenumerator()); mockdbset.setup(d => d.add(it.isany<t>())).callback<t>(sourcelist.add); mockdbset.setup(d => d.find(it.isany<object[]>())).callback(sourcelist.find); return mockdbset.object; }
i had been using add awhile, , works perfectly. however, when try add callback find, compiler error saying can't convert method group action. why sourcelist.add action, sourcelist.find method group?
i'll admit i'm not particularly familiar c# delegates, it's i'm missing obvious. in advance.
the reason add
works because list<t>.add
method group contains single method takes single argument of type t
, returns void. method has same signature action<t>
1 of overloads of callback
method (the 1 single generic type parameter, callback<t>
), therefore list<t>.add
method group can converted action<t>
.
with find
, trying call callback
method (as opposed callback<t>
) expects action
parameter (as opposed action<t>
). difference here action
not take parameters, action<t>
takes single parameter of type t. list<t>.find
method group cannot converted action
because find
methods (there 1 anyway) take input parameters.
the following compile:
public static dbset<t> asdbset<t>(this list<t> sourcelist) t : class { var mockdbset = new mock<dbset<t>>(); mockdbset.setup(d => d.find(it.isany<object[]>())).callback<predicate<t>>(t => sourcelist.find(t)); return mockdbset.object; }
note have called .callback<predicate<t>>
because list<t>.find
method expects , argument of type predicate. note have had write t => sourcelist.find(t)
instead of sourcelist.find
because find
returns value (which means doesn't match signature of action<predicate<t>>
). writing lambda expression return value thrown away.
note although compiles not work because dbset.find
method takes object[]
it's parameter, not predicate<t>
, have this:
public static dbset<t> asdbset<t>(this list<t> sourcelist) t : class { var mockdbset = new mock<dbset<t>>(); mockdbset.setup(d => d.find(it.isany<object[]>())).callback<object[]>(keyvalues => sourcelist.find(keyvalues.contains)); return mockdbset.object; }
this last point has more how use moq library how use method groups, delegates , lambdas - there sorts of syntactic sugar going on line hiding relevant compiler , isn't.
Comments
Post a Comment