score:1

the short answer is: no, because .where() and .select() are extension methods, which cannot be mocked.

the longer answer is: yes, because .where() and .select() on iqueryable<>s do nothing but indicate to the underlying query provider that they were just called. so you could technically create a stub for the query provider and look at what happened to it before it got evaluated.

but the easy answer is: i've found the best approach is to use an actual in-memory representation that is capable of acting like a queryable, like a list. then, rather than trying to validate the lambda expressions themselves, test the resulting data.

var options = new[] {new option(...)};
repositorymock.setup(r => r.context).returns(contextmock.object);
contextmock.setup(c => c.asqueryable<option>()).returns(options.asqueryable());

...

assert.areequal(results[0], options[0].id);

the downside to this is that there's no way to test that your method only uses expressions that can be translated by your query provider. but i generally find this is "good enough" for unit-testing purposes.

score:2

as an option, use your code as a dependency. this way you can stub it without touching context at all. for example:

public class optionservice : ioptionservice
{
    private irepository _repository;

    public optionservice(irepository repository)
    {
        _repository = repository;
    }

    public int[] getoptionswithname(int id, string name)
    {
        _repository.context.asqueryable<option>()
                           .where(o => o.id == id && o.name == name)
                           .select(o => o.id)
                           .toarray();
    }
}

public interface ioptionservice
{
    int[] getoptionswithname(int id, string name);
}

inject ioptionservice into your code with logic similar, how irepository is injected into the optionservice, and stub the method getoptionswithname in the test to return whatever you want.


Related Query

More Query from same tag