Mocking the Model in ASP.Net MVC
The promise of the new ASP.Net MVC framework is better testability through separation of concerns. With that in mind, some folks are talking about how well that goal is realized with the new framework.
One thing that makes testing a little difficult is the fact there is no dependency injection (DI) model built into the current CTP. A recent post by Phil Haack may lead one to speculate that a solution is in the works. A dependency injection model coupled with MVC lets us mock our models and views in more declarative ways.
Instead of waiting for a DI technology, we can use a little elbow grease and roll a pseudo workable pattern ourselves. How can we mock the model? How about this?
1. Use an interface to define your model. Remember? Like you’re supposed to?
1: namespace MvcApplication.Models
3: public interface INWStore
5: List<Category> GetCategories();
7: Category GetCategory(int categoryId);
9: List<Product> GetProducts(int categoryID);
11: Product GetProduct(int id);
2. Add a constructor to your controller that takes an instance of the interface as an argument. With your default constructor, just instantiate the internal member.
1: namespace MvcApplication.Controllers
3: public class BaseDataController : Controller
5: INWStore _dbContext;
7: public BaseDataController()
9: _dbContext = new NWStoreDataContext();
12: public BaseDataController(INWStore dataContext)
14: _dbContext = dataContext;
3. Mock the model in your unit test and pass it in as an argument to the controller constructor. The MVC framework will use the other constructor.
That’s all there is to it. This isn’t new thinking, just a reminder. I was walking through all of the examples and lost sight of this for a little while.
I agree with the MVP debaters that a nicer way to mock the views would be to pass them in as interfaces like we just did to the model, but the solutions being demonstrated by Haack are viable as well.