First, I apologize for the open-ended nature of this question. However, I've been paralyzed by this for months, and in spite of consent searching, still cannot get past this.
I have been working on an MVC/EF app for a while. I'm trying to get an understanding on how to design and build a testable MVC3 application backed by Entity Framework (4.1). You can see a few questions I've asked on the subject here, here, and here.
I'm trying not to over complicate it, but I want it to be a sound, loosely coupled design that can grow. The way I understand it, the following are pretty much bare minimum required components:
MVC app
This is very thin. As little logic as possible goes here. My views have as little conditional logic as possible, my view models are never more than POCOs, and my controllers simply handle the mapping between the view models and domain models, and calling out to services.
Service layer + interfaces (separate assemblies)
This is where all of my business logic goes. The goal of this is to be able to slap any thin client (forms app, mobile app, web service) on top of this to expose the guts of my application. Interfaces for the service layer sits in another assembly.
Core utilities/cross-cutting + interfaces (separate assemblies)
This is stuff I build that is not specific to my application, but is not part of the framework or any third party plugin I'm using. Again, interfaces to these components sit in their own assembly.
Repository (EF context)
This is the interface between my domain models and my database. My service layer uses this to retrieve/modify my database via the domain models.
Domain models (EF POCOs)
The EF4 generated POCOs. Some of these may be extended for convenience to other nested properties or computed properties (such as Order.Total = Order.Details.Sum(d => d.Price)
)
IoC container
This is what is used for injecting my concrete/fake dependencies (services/utilities) into the MVC app & services. Constructor injection is used exclusively throughout.
Here is where I'm struggling:
1) When integration testing is appropriate vs. unit testing. For example, will some assemblies require a mix of both, or is integration testing mainly for the MVC app and unit testing for my services & utilities?
2) Do I bother writing tests against the repository/domain model code? Of course in the case of POCOs, this is not applicable. But what about when I extend my POCOs w/ computed properties?
3) The proper pattern to use for repositories. I know this is very subjective, as every time I see this discussed, it seems everyone has a different approach. Therefore it makes it hard to figure out which way to go. For example, do I roll my own repositories, or just use EF (DbContext
) directly?
4) When I write tests for my services, do I mock my repositories, or do I use SQL Lite to build a mock database and test against that? (See debates here and here).
5) Is this an all-or-nothing affair, as in, if I do any testing at all, I should test everything? Or, is it a matter of any testing is better than no testing? If the latter, where are the more important areas to hit first (I'm thinking service layer)?
6) Are there any good books, articles, or sample apps that would help answer most of these questions for me?
I think that's enough for now. If this ends up being too open ended, let me know and I will gladly close. But again, I've already spent months trying to figure this out on my own with no luck.