A while ago I was looking into dynamic languages (in particular Iron Python) and an idea presented in a talk stuck with me. I wish I could remember who it was to credit them. In essence it was that in dynamic languages unit tests verify what the compiler can't enforce and that we can think of the compiler as simply another unit test in the system. This was obviously framed in a way that meant that the type safety wasn't necessary but lets approach it from a different direction.
Don't unit test what you can use the compiler to enforce.
A common thing I see in MVC examples is a unit testing verifying that some controller action returned the correct type of ActionResult e.g IndexReturnsViewResult. While this test is useful, we can remove it by changing the return type of Index to ViewResult, now the compiler enforces our test for us! This clearly won't work for actions that return different types of result depending on context (this is where unit testing should be testing). But if we can have our compiler enforce some of our specification then I think we should.
It's been a long time since my last post and for that I apologise, my work and personal lives got the better of me. I find I'm a more regular post when I have a series of posts in mind and a clear direction for my writing so I'll be trying to do more of that.
Over the last few months there's been a huge amount of technology released from Microsoft, new versions of Silverlight and the .NET Framework, Azure and the Windows Phone. I'd like to start to work with some of this and document my experiences. As Rob Conery says "Be a Good Jedi: Build Your Own Blog", technically already done, but a rebuild with new technology is a great way to learn better (or possibly worse) ways of doing things.
So Compiled Experience will be rebuilt initially with ASP.NET MVC 2 and Entity Framework (the current version is NHibernate), I'll hopefully be able to integrate some Silverlight into it somewhere as well. I want to try out ELMAH and also have been using the .LESS CSS recently so I'll be using that. This is just the initial technology list I'm sure it may change as things progress and I don't want to limit myself too much yet.
Beyond technologies I really want to push myself to some TDD, without some discipline I find myself in a "Test Later" mindset so trying to get those tests written first will be a challenge. The other challenge will be to ensure any bugs I come across are first verified with a failing test rather than just jumping into the code and trying to fix the issue.
If you've got any questions, comments or suggestions then please let me know.
Lately I've been doing a lot of miscellaneous work in ASP.NET MVC, Silverlight and WPF and some of the differences in approach by their respective development teams is infuriating. The MVC libraries have some of the best examples of how to build a solid library while still allowing developers to override granular pieces of behavior. The amount of extensiblity currently available is amazing (with more coming for validation in the next release).
Compared to this WPF has way too much stuff marked as internal, private or sealed, a good example of how this inhibits some great innovation is "Forget about extending WPF data binding support".
I'm not a huge fan of the IDataErrorInfo interface, it being a kind of hold over from .NET 1.0 DataSet days, so wanted to create similar interface to work with a validation system seperate from the model. WPF has built in support for IDataErrorInfo through the DataErrorValidationRule and my initial approach was to build something similar for my own interface.
Sadly 90% of the code required for DataErrorValidationRule depends on the internals of BindingExpression so no dice. I'm finding it very frustating that something as simple as DataErrorValidationRule couldn't be implemented by a developer outside of Microsoft, what hope do the rest of us have at making meaningful extensions to the way WPF / Silverlight works?
One part of MVC I really liked was being able to quickly delegate from the Controller to the View, with all the built in ActionResults the framework has, I could deal with the shape of the data rather than the formatting, especially for results such as JSON.
One thing that all blogs need is to syndicate their content via feeds (usually RSS and / or Atom), .NET has had a lot of support for Syndication built in since .NET 3.5 with System.ServiceModel.Syndication so building someActionResults to use them is pretty easy.
Our RSSResult is pretty simple, we inherit from ActionResult, take a SyndicationFeed as a parameter. On execution we set the content-type of the output, create an RSS formatter for the feed and write it to the Output Stream.
So far it looks like the dominant pattern in unit testing MVC
Controllers is via a Test Specific Subclass and for some that's a pain.
Especially when you're going to have a lot of controllers, that's a lot
of the same code you'll be repeating over and over. So in the principle
of DRY let's look at using Castle Project's Dynamic Proxy to do away
with these controller subclasses.
The main principle behind this is creating a simple dynamic proxy
and attaching an interceptor to it. We'll then intercept calls to
RenderView and RedirectToAction and then present our captured results
back to the user. The first step is creating our proxy which is simply
a called to ProxyGenerator.CreateClassProxy, this is also where we
attach our method interceptor. We pass constructor arguments as well to
provide support for people who want to use dependency injection with
their controllers.
publicclass ControllerTester<T> where T : Controller
{
privatestatic ProxyGenerator generator = new ProxyGenerator();
private T controller;
private MethodInterceptor interceptor;
public ControllerTester(paramsobject[] args)
{
this.interceptor = new MethodInterceptor();
this.controller = generator.CreateClassProxy(typeof(T), new IInterceptor[] { interceptor }, args) as T;
}
...
}
The
only other interesting piece of code here is intercepting the
appropriate methods "RenderView" and "RedirectToAction" and storing
their results.
However Scott Gu has mentioned that they'll be making it easier to test
controllers in the next version of the mvc framework. But this is still
a decent pattern if you're constantly needing a Test Specific Subclass
to override some methods.