Thursday, December 13, 2007

More Mocking of HttpContext for MVC

I was actually preparing this for a comment to my last post in answer to chris7's comment. But it got long. You know!

Chris7 asked if it was possible to abstract out the Record/Playback syntax in the example to make the code clearer. And you can of course do that and put the Replay call into the MockContextFactory like this:

protected IHttpContext MockContextFactory(string url)
{
IHttpContext httpContext = mockery.Stub<IHttpContext>();
IHttpRequest httpRequest = mockery.Stub<IHttpRequest>();
SetupResult.For(httpRequest.AppRelativeCurrentExecutionFilePath).Return("~" + url);
SetupResult.For(httpContext.Request).Return(httpRequest);
mockery.Replay(httpRequest);
mockery.Replay(httpContext);
return httpContext;
}


The code in the test method would then look this way:



[Test]
public void WorldDetailsRouteExists1()
{
IHttpContext httpContext = MockContextFactory("/World/Details/9/3");
RouteData routeData = routes.GetRouteData(httpContext);
Assert.IsNotNull(routeData, "There is a route to the URL");
Assert.AreEqual("World", routeData.Values["controller"], "We are using the world controller");
Assert.AreEqual("Details", routeData.Values["action"], "With the details action");
Assert.AreEqual("9", routeData.Values["x"], "And the correct x");
Assert.AreEqual("3", routeData.Values["y"], "And the correct y");
mockery.VerifyAll();
}


I actually chose the Record/Playback model as I find it nicer to look at than the other syntax. But I guess it is a matter of taste. In this example it is probably not obvious why I prefer that syntax, but for more involved mocking scenarios it makes it easier to see what is record and what is playback.



Phil Haacked also commented with a post of his own describing how to the same thing using extension methods instead. I encourage you to look at that as well to see yet another way of doing it.



kick it on DotNetKicks.com

Tuesday, December 11, 2007

Mocking HttpContext for MVC route testing

First I have to say thx a bunch to MS for releasing the CTP of the MCV framework. This really is Da Bomb. I think they are doing a great job here.

So I am setting up my first MVC.NET based site, while digging through all the relevant posts on how to use the framework. So while setting up my routes, doing the proper TDD, I stumble upon the MockHttpContext for testing routes in ScottGu's part 2. This bugger is not explained anywhere nor part of the framework. So you have to whip up your own. Googling it - lazy as I am turned up nothing. DIY time. But being the friendly coder, I will share what I made.

So without further ado - here is how you could create a MockHttpContext for testing your routes using Rhino.Mocks. Note, I have used the same way of setting up the routes as Scott is showing in his post.

[TestFixture]
public class RoutesTest
{
protected RouteCollection routes;
protected MockRepository mockery;

[SetUp]
public void SetUp()
{
routes = new RouteCollection();
Global application = new Global();
application.RegisterRoutes(routes);
mockery = new MockRepository();
}

protected IHttpContext MockContextFactory(string url)
{
IHttpContext httpContext = mockery.Stub<IHttpContext>();
IHttpRequest httpRequest = mockery.Stub<IHttpRequest>();
SetupResult.For(httpRequest.AppRelativeCurrentExecutionFilePath).Return("~" + url);
SetupResult.For(httpContext.Request).Return(httpRequest);
return httpContext;
}

[Test]
public void TestRouteRegistration()
{
Assert.IsNotEmpty(routes, "We have filled the routes list");
}

[Test]
public void SearchRouteExists()
{
IHttpContext httpContext;
using (mockery.Record())
{
httpContext = MockContextFactory("/Search/Beverages/2");
}
using (mockery.Playback())
{
RouteData routeData = routes.GetRouteData(httpContext);
Assert.IsNotNull(routeData, "There is a route to the URL");
Assert.AreEqual("Search", routeData.Values["controller"], "We are using the search controller");
Assert.AreEqual("Results", routeData.Values["action"], "With the details action");
Assert.AreEqual("Beverages", routeData.Values["query"], "And the correct query");
Assert.AreEqual("2", routeData.Values["page"], "And the correct page index");
}
}
}
kick it on DotNetKicks.com

Friday, October 12, 2007

CodeBehind handlers in ASP.NET

I was creating an HTTP handler for an ASP.NET project today for returning a CSV report to a customer. And naturally I wanted this to CodeBehind style as everything else. This turned out to be a small gotcha, since it is not supported out of the bag with VS.NET 2005. So for further reference here is what to do.

1. Create the handler as usual - for instance MyHandler.ashx.

2. Create a new code file for the handler - MyHandler.cs - make sure this goes in the App_Code directory otherwise it will not be compiled properly and you will get a "Could not find class: MyHandler" error.

3. Copy all code from MyHandler.ashx to the new code file, replacing all code there.

4. Add CodeBehind="~/App_Code/MyHandler.cs" to the WebHandler directive at the top of the MyHandler.ashx file.

Done deal. Why the code file has to go into the App_Code directory and cannot stay alongside the ashx-file as other handlers do is an open question. I am betting that there is some odd web.config fix for this.

Friday, August 17, 2007

Wierd ActiveRecord "bug"

As I have written earlier I am using the Castle ActiveRecord framework extensibly. It is an extremely cool framework that has cut down on the amount of database work I am doing - shortening development cycles considerably. But I am still learning, and today I finally squashed a very odd bug that had bugged me for a while.

The scenario is this: I am storing some data for the Warlocks game server in a database. This database uses the ASP.NET 2.0 Membership API to store user data as well. The part where I am at right now involves setting up some user data and then using some ActiveRecords. And for some reason this did not work.

The problem, it seemed, was that the schema for the ActiveRecords did not exist in the database. I spent several debugging sessions assuring that I had calld the "Init" method of the AbstractModelTestCase (kindly provided by Castle for making unit testing of ActiveRecords much easier) - which in turn creates the scheme. But the error was there nonetheless.

Working systematically through the test by uncommenting lines to find out what caused the error, I found out that the problem occured when I added the code that added users through the Membership class. Without that it ran fine! I tried adding a new Init call after that code, and the test worked like a charm.

So what is up here? It seems like initializing and using the Membership provider will in some way reset the database. The database is a local file database that is in the project and is copied to output - ie. the data directory. Maybe the Membership framework copies the database file again, thus overwriting the database that has had the Schema created in it. I haven't cracked it yet - but if you know what is happening, please tell me. For now I have fixed my AbstractModelTestCase to initialize the Membership framwork before creating the scheme.

If you are wondering why I am not using a database on a server, it is simply because it is much easier to use a file database so the tests can be distributed to other developers and my buildserver without setting up anything.

Thursday, July 26, 2007

The Interface Tax

Evan has an OK post here, detailing the intrisics of Object Composition and Inheritance. He is very right in the way he is doing stuff, but while I was reading, something was bothering me as well. The thing that bothered me was that the code I am writing in the projects I am doing right now does not look a lot like what he is doing - and I think that I am following the OOP principles just as well as he is. So what is the difference? Actually it is that I am not "paying the Interface tax".

When I had my Advanced OOP course at ITU we really got down and dirty with using interfaces and loosely coupling everything everywhere in the programs, and for a while I followed that road in my stuff as well. But then I began to bug me that for every odd class there was an interface mirroring the methods on that class. Every time I needed new functionality in that class, I off course duly changed the interface. The great thing here is that the only class ever implementing the interface now, and propably forever, was that class that caused the interface in the first place. I call that paying the Interface tax, and in my eye it is a bad case of YAGNI.

I am not saying that interfaces are bad. They are good - for the right occasions. If you find yourself making interfaces for data entity classes, you are probably getting taxed badly. I usually only get to the point of using interfaces when making "framework stuff". Things I know will be used over and over in different projects. In an application, good old inheritance will more often be what I am after. It can save me a lot if implementation by inheriting functionality and save me the hassle of having YAGNI interfaces only being used by one class hierarchy at a time. And you can always refactor into an interface when the need arises.

So before signing up for the interface tax, remember that simplicity is King.

PS. Have you noticed the great TLA for todays topic. *DUCKING*

 

kick it on DotNetKicks.com

Friday, July 20, 2007

The Wii song

This is just SO much fun! SarcasticGamer.com is my new fave RSS feed. Their podcast is a hoot. Honest, no-punches-pulled opinions about the gaming hype sprikled with great radio sketch material. w00t!

Skill mastery in games

Stumbled on this interesting article from Gamasutra on the chemistry of games. Apart from presenting ideas it also tries to give a quick set of tools for evaluating your gameplay too see if it is fun, and maybe find out what is wrong with it. Worth a read, and maybe I should try it out on my Warlocks game - that BTW is getting closer to a playable state, so keep your eyes and ears open for a beta-invite. ;-) As a special treat for those who read my blog, here is the first public screenshot of the game in action. You can't wait now can you?!!! It is made with XNA using stock graphics and free sound effects. It is running on both Windows and the 360.

warlocks

Thursday, July 19, 2007

The Gaming BuzzMetrics

Just tuned in to Allans blog. I know Allan from ITU, having shared the experience of their enrollment course and AI course with him. He is currently employed at Infopaq. His blog is a tech blog, and there are some interesting stuff there.

While stripmining his blog, I cam across a link to the BlogPulse site, where you can make graphs displaying the trends of terms in the blogosphere, ising a technology called BuzzMetrics. Of course I had to take it for a spin in my world - so here is a chart of the Console War in the last three months.

200707190546155mH1FgDwuxaL3Ze5bqup

So it seems as Wii is the most talked about console with the PS3 and MS battling for second place. Not that far from the sales figure truth. Fun to see that the E3 spike seems to have given the Wii most coverage.

BTW, my search criteria for the chart was "XBox" or "Xbox 360", "Playstation" or "PS3" and "Wii".

Thursday, June 28, 2007

Old fashioned learning

Jeff Atwood brought up a subject of lerning today that made me think of the exam I just went to. The notion in his post is about how you learn to learn in college, but also touches on the subject of why todays students are not taught how to use the possibilities of the net. And it is here that my story begins.

Just recently I finished up a course in Efficient AI on ITU. It was a really good course that taught advanced algorithms in many different aspects of the field of AI. During the course we had some smaller programming assignments, and finally the course ended up in an exam. And here the timetrap suddenly clasped. The exam was a four hour written exam. Written as in paper and ball point pen. Now why is it that they can't provide us with some computers for writing our answers? I mea, we are at the Copenhagen IT-University for crying out loud! Is it because we could use the computer to solve the exam? Hardly, if they made sure no compilers were installed on the machine. Heck, if it is a logistics problem - make us bring our own machines. I mean - we were allowed to have every written note we could think of, as well as all the printed material we could carry in there with us. Might as well have brought it in electronic form and save several hectars of fine swedish forest in the process. Of course - then they could not have checked for compilers, but really - it is a course teaching algorithms used in programming, so if you are capable of writing programs to solve tre problems you were gven - is that not a display of your understanding the curriculum? Even if you brought in third party libraries, and had access to the internet you still had to have SOME clue of what they were talking about in the exam questions in order to solve the problems.

I can imagine the kinds of answers to my questions I would get if I posed them to the faculty staff. Most answers would probably be in the region of preventing cheating anf judging people fairly. And while I do acknowledge that some precautions should be taken against people shamelessly copying others work, it would not be that hard to take some electronic countermeasures against it. We are seated in a controlled environment after all. But my main problem is that I think that in the name of paranoia they are making the environment way to controlled - way too far away from an environment where the skills that are taught are to be used.

My proposition is therefore more along the lines of opening up. Giving students the tools they would normally use for the kinds of problems proposed. Yes, even the internet - logging whatever needed to satisfy big brother. The problems could then be made accordingly harder, perhaps requiring a bit of programming or a making the problems easier to solve with programming, but not impossible without. I bet that at the end you would still see the students that have paid attention during the course and prepared properly for the exam being the ones that end up with the good grades. And in the process you would have made sure that the skills related to solving problems in real life - like finding examples and articles on the net - are being kept alive and not treated as "bad stuff".

Luckily my hand got out of its cramp before I got to the celebration beers. And yes, I did get a really good grade. :)

Wednesday, June 27, 2007

How not to keep customers

Having read a lot of posts just like this at the ZMans, I now have my own story to share. Forgive me if this post is badly worded, because right now I am still angry with them for their inexplically bad service. I just got of the phone with the mobile company 3, where I have had a mobile data service for my computer for some time now. The service is being provided via a PCMCIA card with a SIM card in it. The connection is quite OK, and the service is working fine. Now the problem is that since I got my newest laptop, I haven't been able to use the card, since the laptop does not have a PCMCIA slot (it uses Express card instead). Well, I saw that the company had introduced a new series of adapter - a USB adapter - which I would be able to use. So with a hope of getting the thing working again on my machine I call up their sales service, as they do not have any e-mail service what-so-ever. Welcome to the new millennium. And this is from a company that takes pride in introducing next-generation technology.

After wating for a good five minutes - I know, I am lucky - listening to incredibly bad and loud music, I finally get a hold of a female salesperson. After explaining my problem, she puts me on hold for another couple of minutes. When she comes back, she explains to me that it is not their fault that I have chosen to buy an incompatible machine - and since I have been using their product there is no way that they can sell it again. Bottom line - they will not be able to help me with anything. The incredible thing with this is that they are in no way interested in finding out who I am. I could have been a large customer for all they knew. I start explaining that I find that to be incredibly bad service and she just cuts me off. So I ask her to help me with cancelling my subscription. Of cousre she can't do that as she is in SALES, and has to transfer me through music hell to another department.

Here things go smoothly, and I cancel my subscription from the first available date - which by the way is January 15th 2008. And here comes the really good part, because he informs me that the reason they can't help me is because my subscription is still in their 18 month binding period!!! WTF! So if I had been a customer for more than that they could have done something...

I am just confounded by this. Giving extra bad service to "new" customers just seems like such a bad idea. I could maybe have been persuaded to extend my service with them if I had gotten better service. Now they are instead blacklisted as a company I will never ever do business with again.

So if you are reading this I can not reccommend you to do business with them either. Maybe it works for you now - but if you get into a pinch with their technology, don't expect any help.

Thursday, June 21, 2007

A trip to the Castle

In the past week I have been fiddling a bit with the Castle frameworks, because I just had to see what they were up to with Monorail, their Rails for .NET framework. While i think the ideas behind Monorails, and what they have made are technically excellent. There are some things that bug me. I am irritated by the lack of a proper view engine. I think that both NVelocity and Brail are downright messy to look at. Giving me all sorts of ASP like creeps. The ability to use WebForms is in that regard extremely promising, being BOBW - but the limitations they have right now are somewhat prohibiting. Granted, I haven't taken it for a spin yet too see how bad it really is, so I can't be trusted as a real source. I need to do that some day soon.

But anyway, in the process of Monorailing along, I discovered one great little gem. The ActiveRecord. This is a small framework that glues NHibernate and Monorail together, offering a smooth ride through database country. And that one rocks. I haven't used NHibernate much, cause making all those pesky XML files and lugging then along when doing whatever just turned me off big time. But this little bugger just removes all of that and makes it a joyous ride. It even generates the database for you if you're lazy! 8)

So, the latest thing I am working on is using ActiveRecord and plain old ASP.NET, and it is great. Looking for a tutorial to get started are ya? Well - that is already done - head over to Castle and get going!

The next step of Dovization

You have pobably seen the cool but old Dove film on how people were transformed from "ordinary people" into "super models" for use in a commercial. Pretty cool stuff. But this video shows promise of taking that to a whole new level. This will probably make Gibsons virtual actors come true sooner than we think.

Thursday, June 07, 2007

Randomness of Random

Stumbled on this post on random numbers in games, and found it cool. It used to irritate me to the point of lying awake that my random numbers just weren't that - that was back in the old Speccy days. But now, knowing the pain randomness brings to TDD, I am entirely happy with the fact that random numbers (like friendly fire) aren't.

BTW, while you are at it, post some songs wishes for Rock Band. I am so looking forward to this game. It will take my Guitar Hero addiction to a whole new level probably. Last major GH thing - 5 stars on YYZ (Medium). Didn't thik I'd get it when the song was over, but it cam home by a small margin. The question is if I can get those 3 stars on Woman (Hard) BEFORE I 5 star every song on medium...

Microblogging

So, at Reboot this year I learned that microblogging is the new, new thing. Since Twitter does not have an SMS interface near DK, I am into Jaiku. So you can join me here.

Back to strongarming, eh?

I have been following the Cansdale vs. Microsoft case for a while. And Jamies post today did it for me. The way Microsoft is acting here disgusts me. He has been pouring hours into making an awesome add-on for their product, which is helping both professional and the open community in deveopling better products. And they are strongarming him on vague grounds because their product is not as "flawed" as they claim.

A signal is sent to the entire open source/add-on community that spending your time supporting their product is a bad idea. Just another brick in the yellow brick road that could lead "alpha geeks" away from MS - as have been the community buzz for a while now.

Well this has done it for me as well. I installed SharpDevelop and will be working with that from now on. The new version is actually awesome, i just need to find out how to enable a shortcut for run tests, as this is the way I work with TestDriven.NET today... It doesn't seem to work. Oh, and I have to figure out how to make XNA projects with SharpDevelop as well - then it is a total bye bye.

Maybe Jamie could be convinced to make TestDriven.NET's features in SharpDevelop instead. Their TDD tools are not that good. :o)

 

kick it on DotNetKicks.com