I work with a team of talented developers who adhere to the “Three Rules of TDD” which are:

  1. You are not allowed to write any production code unless it is to make a failing unit test pass.
  2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
  3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.

To adhere to those three rules, we use various tools and frameworks that help us write appropriately-failing tests before writing the production code that make the same tests pass. One of those excellent tools is a mocking framework. Mocking allows us to take advantage of polymorphism and abstraction, creating “pretend” implementations of our dependencies so that our unit tests stay “unit tests”… only testing one small section of code at-a-time.

One area where we constantly run into issues is when we are mocking a dependency that takes a complex argument like an “Expression”. Expressions and Funcs are really useful because they allow you to write code that gets executed later on. However, Expressions and Funcs are especially hard to mock. Not impossible… just hard.

Here’s an example of one such dependency:

Every time I find myself mentoring another developer in mocking techniques, inevitably we arrive at a “query” method like this. A query method on a repository is very useful to the code that consumes it, but it’s not very straightforward when mocking. Here’s a test I’m working on right now:

Problem with this test is the way I’m setting up my Query method. This will not work. Do some google searching to find out why… out of scope for this article. HOWEVER, the way I’m doing this is expressive and makes sense. I need something that works and reads well.

Many of the examples on the web take the “easy way out” and lift any constraints on the mock… here’s an example using Moq:

Trouble is, that breaks rule #1: “You are not allowed to write any production code unless it is to make a failing unit test pass.” Because the test doesn’t care what you pass in to your query method, your production query actually goes uncovered by the test… you just wrote production code that didn’t actually cause a unit test to pass or fail.

In order to properly constrain a mocked method like this, you need to test the expression against actual objects to see whether or not the expression returns true or false… in order words, you need to find out if the given expression “matches”. For example, here’s how I’ve mocked a query like this in the past:

This works okay for simple queries. But it is ugly and unexpressive and doesn’t really handle things that you DON’T want… only what you DO want. So, then you have to feed some objects that you don’t expect to match… at this point we’re need to capture the expression at runtime and run it against a list of objects. Here’s an example:

Messy. First off, we have an extra test obsevation JUST to test the runtime expression. But, I don’t want to TEST the expression! I simply want to constrain the mock method so that it only returns the expected objects IF the right expression is passed in. Secondly,  my test is harder to understand because of the list of unexpreissive test objects.

Time for something different. How’s this look?

Here’s the finished test:

Now, my test is looking better. I’m back to constraining my mock instead of testing a runtime argument. Also, the “fluent” flow is quite a bit more expressive. It almost reads like plain english. I think I’ll have an easier time explaining this to others using this form.

If you like it, feel free to use it! You can either copy the code from github or just install a nuget package. My code uses Moq Mocking Framework. But I’m sure you could adapt this to your favorite mocking framework with a few minor changes.

PM> Install-Package AcklenAvenue.Testing.Moq

 

You can also check out the source code at Github. If you’d like to improve the code, feel free to submit a pull request! Enjoy!

  • Neil Crawford

    Correct me if i’m wrong but this just seems like a strict mock on the query you’re passing without actually testing the query itself?

    If you want to keep the generics perhaps you could define the expression elsewhere and have a query provider class that returns it then run a unit test with some real test data turned into a queryable. It’s kind of like a flavour of the repository but without having lots of repositories you just have your query expressions provided to the generic repository.

    I tend not to put the actual queries in with business logic for this very reason and abstract them behind a function in a repository then it’s easier to set my expectations on what data I expect back.

    I quite like the idea of being able to do this querying and losing the overhead of many repositories.