Archive for the ‘ASP.NET’ Category
One of the most useful things I came across when doing the asp.net project that i wrote about in my last 2 posts was this article and sample solution by Jason Bock on mocking the HttpContext session state in .net 1.1 and 2.0. Actually this is not a ‘mock’ interface in the sense of mock objects but a real HttpContext which is artificially built by calling into some API’s and which can be used in non web scenarios. I’ll explain why I needed this and how I used it below.
I had to make use of caching in the solution and started of using the HttpRuntime Cache which can also be used from non web applications and is very useful when driving your app through NUnit. Of course, with my new found love of interfaces and mock objects i wrote up an ICacheHandler interface and implemented a WebCacheHandler that wraps the System.Web.Cache. I did consider using EntLib but i dont really need any offline caching etc. System.Web is more than enough. This cache is a dependency for the Service Agent so i stuck my DI hat on and injected it into the service agent through the constructor.
Now heres a gotcha. If you simply use the System.Web.Cache object and try to call the Add() method, then when there is no web context (say when you are unit testing), the Cache will be null and you will get an “object reference not set to instance of an object” errors. So you need to use HttpRuntime.Cache.Add() .
We then decided that for certain situations the application level caching could actually prove counterproductive and what we really needed was Session level caching. There isnt much data to store anyway so theres no chance of knocking down the server with all the session level caching. Since I had my nice lCacheHandler, i wrote up another SessionCacheHandler to use session state. This is where the wheels fell off for a couple of hours. Session state is not like the HttpRuntime Cache. It cannot exist without a valid HttpContext (which is rather obvious and sensible and all that but not helpful in that situation) so the system which was working with the WebCacheHandler when called through NUnit now simply barfed at all calls to add data to the cache.
I knew i had to fool the system into thinking there was a valid HttpContext so i could test the code properly offline without needing to launch the web application so after trawling through the web i found the article by Jason Bock (linked above). The way i used this tool was to set a dependency on HttpContext in my SessionCacheHandler and allow a HttpContext to be injected via property injection. A CacheHandlerFactory class then does the job of setting up the session handler and injecting either this MockHttpContext or the real HttpContext.Current and returning the sessionCacheHandler for use by any caller. This works fine now and i can peacefully run the tests without needing a full web context.
Thinking about EntLib again, i guess a more EntLib oriented approach would be to make this custom component into a sort of ‘SessionCache’ provider for the Caching Application Block and let entlib read a config setting. That way it can also be used through PIAB. Gotta start looking into that option now at least for self education.
It should be interesting to see whats coming up in ASP.NET 3.5 . Apparently there are lots of interfaces for these static things like HttpContext etc which will allow them to be mocked or substituted at runtime/testing so maybe this kind of thing will get easier as time goes on. Meanwhile, i’ve got a nice addition to my toolset. I’m beginning to really like dependency injection. Now for the next step – DI Containers!!
[UPDATE- 18 Feb 2009]: Just to point out that there are limitations in Jason’s utility. It is good for session usage but I ran into problems when I wanted the HttpContext to have stuff like Physical Application Path and things like Headers in the context which cant be done through Jasons code. So the tool that i then turned to was Phil Haack’s HttpSimulator. This was incredibly useful when developing MockingBird.
In my previous post, i talked a bit about using the Model View Presenter in the ASP.NET project im doing and the videos of Jean Paul Boodhoo and others that gave me the necessary material to do the work.
The thing that most impressed me with JPB’s videos was the use of Mock Objects. I have been aware of them for a long time but never had any reason to use them, being primarily in the Biztalk world. I have recently read about using IoC/DI & mocks in pipeline components and custom adapters but have never had the chance. I was pleasantly surprised to find that i had quite underestimated what can be done with mocks. I always saw them as ‘fake’ data suppliers and didnt realise how you nicely can test the behavior of the system with them. I’ve adopted them wholesale now and have quite fallen in love with the approach of mocks and depedency injection. If only we could unit test Biztalk like this!!
I decided to keep things simple and have used only NMock2. The best article i found is in MSDN Magazine – Exploring the Continuum of test doubles. This is a really good resource explaining the range of different types of test helpers- dummy data, fakes, stubs, mocks and so on. I had a brief look at Rhino Mocks and it seems very powerful but reading through the material on the new kid in town , MoQ, i think i will go with MoQ in future as i dont quite get the point of the Record and Replay syntax of Rhino and others. TypeMock seems quite brilliant too with its ability to mock concrete classes as well which, IMO, is a boost in brownfield systems that dont have (m)any interfaces or opportunities to inject things into the system under test. I dont think MsTEST has any mocking capabilities yet, but maybe there is ..
But the time i spent researching mocks brought to light just how much (mostly) pointless academic debate there is about these things. There are heated debates on blogs about whose approach is ‘purer’, classic TDD vs. mockist TDD and all sorts of things. To some extent, these discussions are educative, but then they soon descend into weird stand-offs which does no one any good. This is why i have taken a liking to the approach in MoQ – mainly because Daniel Cazzulino (kzu) and the other Clarius chaps who started it seem very pragmatic rather than being stick in the mud purists. Check out some of Daniels posts here , here and here ) These tools are all good, Rhino, NMock2, MoQ, TypeMock and we should be highlighting their strengths and applicability to different situations and getting more people using them rather than arguing over whose approach is the right one. Lets face it, NO ONE is going to agree on what ‘correct’ OO design is (if there is such a thing). Interfaces are great, but they can be overused. Classic TDD state based tests are great but only for state testing.. Mocks are great but just for behavior. There are those who think that even using mocks is a ‘smell’ Heck, to some folk, using X is a ‘smell’ and to others not using it is a ‘smell’. Frankly, these debates stink. 🙂
If i hadnt started seeing a glimmer of light with my simple forays into NMock i would have avoided mocks altogether, actually, i would even avoid TDD altogether if i were to pay much attention to these silly arguments and posturing. If you can write all your tests first, good. I’m happy for you. Just because i write some tests before and some tests after, doesnt mean i care less about my code. And yes, according to me its perfectly fine to buy/use a tool that will generate unit tests for my code because, at the end of the day, i want the code to be tested (actually i dont use any test generators… yet…) . I agree theres less code to write when you write the test first (or at least stub out your expectations) and you’re more likely to write better quality code in small increments but when you inherit a project do you care what came first, as long as there is a good set of tests?
Anyway, enough of my rant..but hey, i do feel better for having got that off my chest!!. So, back to the point, i used IoC quite a bit, injecting views into presenters, service agents into presenters, services into service agents etc and ended up covering the codebase with a wide variety of tests even before i wrote a single aspx page. I enjoyed the opportunity to think through the behavior of the system in a white box manner rather than just relying on state based tests. I do have quite a few state based tests now but only wrote them when i had exhausted all tests on behavior and had to check the exact return values.
Having done all this, i was overjoyed to go back to the old orchestration designer when i had to add a couple more features to one of those backend services. It seemed like a trusty old friend not like those weird GridViews and their datasource pals!!! … Mocks are cool, maybe we will see more of them in the biztalk world, but for me personally, i cant wait to finish off the ASP.NET and go back Biztalk and WebServices.
Whew!! This has been a long time since i managed to put pen to paper as it were and post anything here. I’ve been spending a few weeks away from Biztalk in the murky world of ASP.NET. Its been an exhausting time but a great learning experience and lots of fodder for a set of blog posts. So, whats a Biztalk guy doing with ASPX then?
Well basically once we got the Oracle adapter working somewhat decently and linked up the needed systems, we were tasked with adding some aspx forms to interact with a couple of the services. Having volunteered for the task back when it was originally envisaged as a one man project (featuring yours truly) I had to come good on my promise. It is only a small aspx system, 4-5 pages with a few grids and data displays linked to the two backend services.
I could have gone down the standard webforms route, but with our main portal being implemented with Model View Presenter, i decided that to keep things consistent I would have to use the MVP pattern. Couldnt choose MVC though cos its still all .NET 2.0 and MVC isnt RTM anyway so that was out. The two main resources that kickstarted my foray into the MVP world were Jean-Paul Boodhoo’s videos (MVP, TDD-1 and TDD-2) for DotNetRocks TV as well as his excellent article on the same subject for MSDN Magazine. I highly recommend watching the DNRTV videos and although the TDD ones pre-date the MVP show, its better to start with the MVP show cos JP had introduced MVP in the TDD videos and sparked an interest and that led to him doing an entire show on MVP. I also spent some time with the videos on Polymorphic Podcast – their Design Patterns Bootcamp- MVP series. All of these are excellent.
I found myself leaning more towards the Passive View approach that JPB favors rather than the Supervising Controller which is the approach shown in the Polymorphic Podcast set. It seemed to me, when i first saw the show, that keeping the view to a complete minimum was definitely the way to go. Ironically, over the course of the project i found that i ended up doing more of the Supervising Controller particularly because rendering the gridviews play a major part in the system and so theres a huge amount of code in the view. Not business logic, mind you, but lots of display logic, databinding and so on. I think the Passive View approach is rather hard to do well when you have a fair amount of databinding to do and i really dont think the presenter should know that the View is using a grid or any specific control as it would make them too tightly bound.
Since there isnt any business logic as such , I elected to use a DTO library to pass data through the view – presenter – serviceagent layers. The serviceagent wraps the two proxies of the webservices and maps their structure to the simpler DTOs. It took me sometime to get my head around the page lifecycle and the way databinding works with custom object collections. Basically the gridView doesnt work well with the MVP (at least, when using Object data sources) because in the webforms world, the view is king and takes control immediately. So if you specify an object data source, the grid will immediately call into it and try and get the data from wherever the object points to , but in the MVP, we want to push the data into the grid so the grid wont get anything by simply initialising the collection. So I ended up having to dynamically databind and before that to serialize the collection into a DataView so that paging and sorting the grids became simpler. I didnt want to implement all that kind of paging and sorting logic into my DTOs. I read David Haydens article on using the WCSF Object Container Data Source when using grids with the MVP approach but by then i had got the dataviews to work so i didnt bother trying that out. Will file that away for future reference.
I can see why people struggle with the webforms model and why the MVP and MVC approaches are gaining so much popularity. Declarative stuff is alright but only as long as you buy into it wholesale and are willing to lose some control over the way the system works. Yes, it works for lots of systems, but personally i prefer to take more control over my system and the MVP gives me that. Im quite looking forward to trying my hand at MVC (only a little bit).
One thing my experience with the gridView and the hours i spent trying to style it exactly to match the mockup screens that formed the spec taught me was that CSS and layout are not my cup of tea. I still havent got the pages to look like they are supposed to. They work and in a very robust way (yeah, i would say that wouldnt i?) but they dont look impressive. The reason im confident about the system will be dealt with in the next post.
So, in summary, IMO, the Model View Presenter is great but hard to do right.