Sql – Unit testing Linq 2 Sql lazy-loaded properties

asp.netlinq-to-sqlormtddunit testing

Lets say I have a Customers table and an Orders table with a one-to-many association (one customer can have multiple orders). If I have some code that I wish to unit test that accesses a specific customer's orders via lazy-loading (e.g. a call to customer.Orders), how do I mock / stub that call out so that it doesn't hit the database?

Edit:

To be more clear, let's use a more concrete example. Let's say I want to return all the orders for a particular customer. I could write it like so using the auto-generated lazy-loading properties Linq 2 Sql provides:

Customer customer = customerRepository.GetCustomerById(customerId);

return customer.Orders;

However, unit testing this is a bit tough. I can mock out the call to GetCustomerById, but I can't (as far as I can tell) mock out the call to Orders. The only way I can think of to unit test this would be to either a) connect to a database (which would slow down my tests and be fragile) or b) don't use lazy-load properties.

Not using lazy-load properties, I would probably rewrite the above as this:

return orderRepository.GetOrdersByCustomerId(customerId);

This definitely works, but it feels awkward to completely ignore lazy-load properties simply for unit-testing.

Best Answer

As an overall answer to your question, you stub out that call just as you stub out anything else.

I will assume that the code you want to unit test is a consumer of your data access component, as this is the most common scenario. You can only stub out you data access if you program against an interface. This means that you must hide the implementation details of L2S behind an interface such that the consuming code has no idea about which implementation it currently consumes.

A corrolary to this is that lazy-loading is an implementation detail you you need not worry about when unit testing, because the unit test should not be using L2S at all.

When stubbing out the data access layer, a call to customers.Orders would typically be a call to an in-memory property of the Stub.