I have now coded away for a while and it’s time to reflect a refactor a bit. I don’t like code lying around that I might not need. YAGNI you know…
So I thought I’d give it an hour to clean stuff up. And maybe put some better looks on the site. Hopefully I’ll end up in a better place. Here are the things I have planned:
- Remove all the Views and Controller methods that I’m not using
- Bring in a theme for the site
- Shape up the lists on the first page
- Create a page object to write my acceptance tests against
- Introduce a read service for the site – the start of my CQRS initiative
Man – that looked long! But most of them are small. Just imaging how much better the code will be afterwards.
Here we go.
Remove unused stuff
OK – I love the MvcScaffolding ideas but, as I wrote here, I’m having some trouble with the code it’s generating. In this case – I’m not even sure that I will need all the views and controller methods. Maybe I would have been better of by just generating the repository.
Not use crying over that – I’ll just remove the views and action methods of the controller that I’m not using. So under Views/Kanbanboard I removed all the .cshtml (Razor) files except the Index.cshtml which is the page we’re using.
There – much better. Ooops – almost forget. Better run my specs and tests. There – they run fine. I feel better.
Add a nice theme for the site
OK – me and layout. That’ll make a lot of people laugh. Hard and long… But I’ve found a codeplex project that helps me and others in this situation. From there you can download a number (50+) project examples. I did that and choose an example. But this is for aspx pages and MVC 2. So I needed to convert them.
The process was pretty straight forward but made me realized how much I lack in understanding of these concept. I use a template based on BluePrint CSS (which is an awesome idea for lost people like me) and tweaked it. And tweaked it. And then tweaked it some more. I’m still not happy. For a while I thought to myself that maybe this is designing – but that can’t be…
OK – I need help. I’ll leave it like this. It’s better but not even OK I think. I’ll get some help on this one.
Here are the before and after shots:
Shape up the index view and keeping it DRY
I’m not happy of with the lists on the index page right now. I want something condensed that can be shown on a row. Maybe two with the thumbnail on top of the text. This is also layout stuff that I don’t know much about.
But first – I’m looping over two collections of KanbanBoards, creating the same HTML. That doesn’t feel DRY at all. So I used the Html.RenderPartial() – method like this:
And then I created this partial view that just creates a row for one KanbanBoard:
OK – that’s ugly, but at least it’s DRY. I’ll get help on that too.
A little less brittle, please
OK – that was a part that I’m wasn’t very comfortable with. Hmmm really need to do something about that. I’ve put this on my reading list. But now I’m back in C# (at least) and thought that I could refactor the acceptance test a bit.
One problem with going against the GUI is that you have to get a hold of the items you want to interact with somehow. And they have a tendency to … move or change. So when I write code that goes against a certain tag, with a certain class or id or even worse a certain placement in a page – I stand a big chance that the test might fail just because somebody has renamed or move things on the page. And that is very likely to happen.
And this adds to the problem we call brittle tests. Brittle test will soon fail for reasons that the current developer doesn’t know about. And they are not run.
There are a lot ways to manage this and I’ve found an excellent series (in Ruby but we have a lot to learn from them I think) on these matters. The first thing that is suggested is to introduce a PageObject that sits between your test and your HTML. Your test code is now decoupled from your HTML – we like decoupling.
Right now the difference in brittleness (hey, that was a word !?) in the tests, but as we progress and create more and more interactions (clicking links, filling out forms etc) we will have more and more use of them.
Here is my first stab of a page object for my home page, with loads of concepts shameless stolen from Cheezy World:
Well that – felt pretty nice. But I see room for improvement. I created an abstract base-class that encapsulates some stuff that all page objects need. Here’s that class:
And that shaped up my HomePage object into this:
And all this together gives some pretty clean step definitions:
And the test still runs! I’m allowed to enter the next stage
Read service – the start of CQRS
I have already sung the CQRS praises but it feels so right I have to include it here. I’ll start as I usually do – simple and small. Here it will be by introducing a read service that get me my view models.
In the NCQRS example they use a DBContext and simply let that be the read model. That pretty much sums up what I’ve done up to now. But I want to formalize it a bit more. So I was thinking that I might introduce a application service (DDD-style) and call the repository from there.
So I wrote these tests in a new Tests project. But first – I never grow tired of this:
Install-Package NSubstitute Install-Package ShouldFluent Install-Package NUnit
Here’s the tests…
Eeh … I’m back. I got into to it, I’m sorry. As I started to code out the test I couldn’t help myself. Sorry. Here is a short version of what I did:
- I created a test project and wrote that first test for a ReadService that returns ready packed ViewModels.
- I then created a new Class library called … ReadModel.
- Into that I moved my ViewModel, Domain (KanbanBoard since it’s just a read model anyway), Repository and DBContext to go with it.
- I didn’t move the database (as they did in the NCQRS example) since I don’t feel comfortable with a .dll holding on to my database.
- I refactored and cleaned up for a while – and then I could run the tests again. Oh that feel so good – tests are a warm blanket that wraps around me in refactoring times.
Well – that’s pretty much it. It’s a bit over refactored now but feels good.
Reflection and conclusion
I did a lot of small changes in this post. In some areas I was way out in the deep, so I have to get back to them. Yes the layout stuff. But other felt really good to do. I especially liked to introduce the Page Object stuff.
Next up is to start creating Kanban boards.