Presentation Logic & Semi Integration Tests
However, his answer to this issue involves basically executing a dynamic page (in MonoRail) and testing the HTML output. He admits that this is a "semi-integration test". I would agree with that, except for the "semi" part. If I really wanted to execute a page at the unit testing stage, I could use a tool like NUnitAsp, which operates at the same level of abstraction as ASP.NET server controls and thus insulates the test code somewhat from the actual rendered HTML markup.
I call it semi integration test because the only part of the code that I exercise is the view code, and it is integration because I have to verify the textual result, rather than the objects themselves.
Scott's suggestion about using something like NUnitAsp is a true integration test, because it execute the entire pipeline, including the controller, data access, etc. That is not the purpose of the test, I just want to validate presentation code, not the whole thing. NUnitAsp is also not applicable because it uses WebForms, which is not something that I willingly use.
Another very good point Scott is making:
Finally, forget testability for a minute and consider something I was taking for granted. Continuing with the banded report example, what happens when the subtotals are needed in a different view? Or in the output of a web service? If that calculation is buried inside a specific view, look at the bright side: At least you'll have plenty of opportunity to practice your refactoring.
If I need it in more than a single place, then it would be the time to consider refactoring. If I needed it in another view, I would probably refactor to a subview, which is a ridiculously easy to do. I doubt that I would need to do it in a web services, since that is calculable information, and would usually cause more harm than good.
At any rate, I feel that pushing this to the domain level is not something that I would really want to do, it is purely presentation logic, meant for the user, without any correlation to the domain. If I had to use it in several places, I would a presentation layer class that would take care of it, but that is still presentation logic.