Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should methods containing LINQ expressions be tested / mocked?

Assuming I have a class with a method that takes a System.Linq.Expressions.Expression as a parameter, how much value is there in unit testing it?

public void IList<T> Find(Expression expression)
{
    return someCollection.Where(expression).ToList();
}

Unit testing or mocking these sorts of methods has been a mind-frying experience for me and I'm now at the point where I have to wonder whether it's all just not worth it.

How would I unit test this method using some arbitrary expression like

List<Animal> = myAnimalRepository.Find(x => x.Species == "Cat");
like image 617
Phil.Wheeler Avatar asked Feb 28 '23 03:02

Phil.Wheeler


1 Answers

It is a bit artificial to unit test this, since each LINQ provider is implementation-specific. You might use various different approaches in your test, and it simply won't tell you anything about the real implementation. For example, if it is mocked via LINQ-to-Objects, I could use:

List<Animal> = myAnimalRepository.Find(x => CheckSpecies(x, "Cat"));
...
static bool CheckSpecies(Animal animal, string species) {
    return animal.Species == species;
}

That will work with LINQ-to-Objects... but only with LINQ-to-Objects. Likewise, a UDF usage (or one of the SQL helper methods) will work in LINQ-to-SQL but not Entity Framework.

I've reached the conclusion that only integration tests are useful for this scenario, so no; mocking isn't very helpful here. It will give you a warm happy feeling that you've done something useful, but ultimately it doesn't test that what you write in your app will work.

An even better approach, IMO, is not to expose such over your repository interface. If you limit the LINQ queries to your data-layer you remove the risk and now you are testing (/mocking) a pure, predicatable interface.

I discuss this more here.

like image 176
Marc Gravell Avatar answered Mar 07 '23 15:03

Marc Gravell