rickardnilsson.net is a weblog and the online home of web developer and father of three, Rickard Nilsson... More
Rickard blogs about creating software solutions using ASP.NET and agile practices.
After I posted my Code Kata Cast I received some feedback regarding the ReSharper templates I use to speed up my coding. I decided to share them with the public (like so many before me) in hope that others may benefit from them, as I do.
rickardn-resharper-templates.zip (1,44 kb)
After you’ve downloaded the zip-file and unpacked it, open Visual Studio and the ReSharper Templates Explorer: Menu –> ReSharper –> Live Templates…
Click on Import… as the screen shot below shows, and find the file “rickardn-resharper-live-templates.xml”
Then click the “File Templates” tab and repeat the procedure for the “rickardn-resharper-file-templates.xml” file.
Good luck with your katas!
Have you ever come across the concept of a Code Kata?
For me it really took off after reading blog posts (1, 2, 3) by Unce Bob Martin and Pragmatic Programmer Dave Thomas. The concept is really simple: how can we, as programmers, better our selves and improve our techniques and proficiency in using the tools and processes in our every day work?
The suggested solution is inspired by the martial arts kata. You learn how to implement a solution to a specific problem and you practice all the moves in the exact same order over and over again. The point is that you should know the moves so well that you forget about them and focus on improving your key strokes and the use of your tool set. The never ending goal is to perform the kata with the least amount of key strokes.
The promice is that practicing these kata's often and regularly makes you a better and more productive programmer in that you are trained to act instinctively in certain reoccurring situations.
Anyway, I've been practicing a kata based on a problem initiated by Roy Osherove and I decied to record it to get some feedback and maybe spread some knowledge on how I practice Test-driven development using ReSharper.
Calculator Code Kata Cast 1 from Rickard Nilsson on Vimeo.
Roy Osherove is giving an hands-on TDD Masterclass in the UK, September 21-25. Roy is author of "The Art of Unit Testing" (http://www.artofunittesting.com/), a leading tdd & unit testing book; he maintains a blog at http://iserializable.com (which amoung other things has critiqued tests written by Microsoft for asp.net MVC - check out the testreviews category) and has recently been on the Scott Hanselman podcast (http://bit.ly/psgYO) where he educated Scott on best practices in Unit Testing techniques. For a further insight into Roy's style, be sure to also check out Roy's talk at the recent Norwegian Developer's Conference (http://bit.ly/NuJVa). Full Details here: http://bbits.co.uk/tddmasterclass bbits are holding a raffle for a free ticket for the event. To be eligible to win the ticket (worth £2395!) you MUST paste this text, including all links, into your blog and email Ian@bbits.co.ukwith the url to the blog entry. The draw will be made on September 1st and the winner informed by email and on bbits.co.uk/blog
Roy Osherove is giving an hands-on TDD Masterclass in the UK, September 21-25. Roy is author of "The Art of Unit Testing" (http://www.artofunittesting.com/), a leading tdd & unit testing book; he maintains a blog at http://iserializable.com (which amoung other things has critiqued tests written by Microsoft for asp.net MVC - check out the testreviews category) and has recently been on the Scott Hanselman podcast (http://bit.ly/psgYO) where he educated Scott on best practices in Unit Testing techniques. For a further insight into Roy's style, be sure to also check out Roy's talk at the recent Norwegian Developer's Conference (http://bit.ly/NuJVa).
Full Details here: http://bbits.co.uk/tddmasterclass
bbits are holding a raffle for a free ticket for the event. To be eligible to win the ticket (worth £2395!) you MUST paste this text, including all links, into your blog and email Ian@bbits.co.ukwith the url to the blog entry. The draw will be made on September 1st and the winner informed by email and on bbits.co.uk/blog
I've been working to get my head around the Model-View-Presenter pattern and I've focused primarily on a Winforms scenario. As it turns out there are numerous sources out there on MVP, some of which are focused on Winforms, e.g. [2, 8] and some which are not focused on Winforms but highly valuable just the same, e.g. [1, 4].
Figure A. Screen mock up
However, none of the referenced sources discusses the issue of communication between MVP triads. All of them thoroughly discusses the ins and outs when you have a single presenter talking to a single view and a single model, but nothing about communicating with other MVP sets. I've also found that other people are also struggling with this problem and how to best solve it but no really good solution has presented itself.
Well, we start with an example to formulate the problem. If we look at the example of the humble dialog [8] this only covers a single triad so we make it slightly more complicated. We have two views, a parent view and a dialog view, and each view has an associated presenter, i.e. parent presenter and dialog presenter. Now, the requirement is that when a user clicks a button on the main view the dialog should pop up modally giving the user the possibility to change a property value. The value change should then be reflected in the parent view. Sounds simple enough, right?
The problem is to implement this leveraging the MVP pattern to achieve a loosely coupled, highly cohesive, and test friendly solution. Some of the questions are; who has the responsibility to create the dialog view, who has the responsibility to show the view, what is the result from the dialog view and who should act on it.
There are many different ways we can go about doing this but since I'm into Test-Driven Development I'm gonna do it test first. I also like to do UI up front so I create a Winforms project in Visual Studio and start dragging and dropping. The simplest possible screens are shown in figure A.
OK, now let's start with our first test. We want the dialog to appear when the "Edit user name" button is clicked and following MVP the view should simply pass on control to its presenter. The parent presenter should then have the dialog view popping up. This is the first test using Rhino Mocks [3]:
[Test] public void ParentPresenter_EditUsername_should_open_a_dialog() { var view = mockery.DynamicMock<IParentView>(); var dialogPresenter = mockery.CreateMock<IDialogPresenter>(); using (mockery.Record()) { dialogPresenter.Load(); }
using (mockery.Playback()) { var presenter = new ParentPresenter(view) { DialogPresenter = dialogPresenter }; presenter.EditValue(); } }
The parent presenter should simply pass the control to the presenter of the dialog. Thus, the parent presenter has a dependency on the presenter of the dialog and the dependency is injected through a property:
var presenter = new ParentPresenter(view) { DialogPresenter = dialogPresenter };
Now, these interfaces and classes doesn't exists so first we have to create them. But before we do I see some code that has no test, namely dialogPresenter.Load(), so let's write another test:
[Test] public void DialogPresenter_Load_should_call_show_on_view() { var view = mockery.DynamicMock<IDialogView>();
using (mockery.Record()) { view.Show(); }
using (mockery.Playback()) { var presenter = new DialogPresenter(view); presenter.Load(); } }
So, the presenter simply tells the view to show itself. Remember that we're talking to an interface and that the view in the test is not the real implementation. We're only driving out the behavior of the presenter at this point but we're doing it in such a way that the view implementation should be as thin a possible.
I'm using ReSharper [7] to generate the interfaces and classes that I dreamed up in the tests.
When the initial tests are passing let's move on. The next thing that should happen is the user providing a new user name in the dialog and clicks on OK. So lets write a test for the OK event. I realize that some refactoring is also in place:
[Test] public void DialogPresenter_ChangeName_should_change_value_and_close_dialog() { var model = mockery.CreateMock<User>(); var callBack = mockery.CreateMock<Action>(); var expectedName = "foo";
using (mockery.Record()) { Expect.Call(dialogView.Username).Return(expectedName); dialogView.Close(); callBack(); }
using (mockery.Playback()) { IDialogPresenter presenter = new DialogPresenter(dialogView) { Model = model }; presenter.NameChanged += callBack; presenter.EditName();
Assert.That(model.Name, Is.EqualTo(expectedName)); } }
The last requirement states that the user name change should be reflected in the parent view. There are a couple of ways to do this but in this example I'm gonna go with the Observer synchronization [6] strategy because it provides a nice separation of concerns and is easy enough to mock. Note, however, that it is the presenter which acts as the Observable, not the domain object itself (User in this case). This is because I do not want to polute the domain model with event code. The previous test verified that a callback method is called whenever the name in the dialog is changed. Now, the parent presenter only has to hook up an event handler to the dialog presenter's event. Our next test shoes what should happen in the parent presenter when the event is triggered:
[Test] public void ParentPresenter_Update_should_update_view() { var model = new User {Name = "foo"};
using (mockery.Record()) { Expect.Call(parentView.Username = "foo"); }
using (mockery.Playback()) { var presenter = new ParentPresenter(parentView) { Model = model }; presenter.Update(); } }
So, the presenter explicitly tells the view what to do. The parent view is an example of a Passive view [5]. The presenter's code is included below for completeness:
// Parent Presenter public class ParentPresenter { private readonly IParentView view;
public ParentPresenter(IParentView view) { this.view = view; this.view.Presenter = this; Model = new User(); DialogPresenter = new DialogPresenter(new DialogView()) { Model = Model }; DialogPresenter.NameChanged += Update; }
public IDialogPresenter DialogPresenter { get; set; } public User Model { get; set; }
public void Load() { view.Show(); }
public void EditValue() { DialogPresenter.Load(); }
public void Update() { view.Username = Model.Name; } }
// Dialog Presenter public class DialogPresenter : IDialogPresenter { public event Action NameChanged; private readonly IDialogView view;
public DialogPresenter(IDialogView view) { this.view = view; this.view.Presenter = this; }
public User Model { get; set; }
public virtual void Load() { view.Show(); }
public void EditName() { Model.Name = view.Username; view.Close();
if (NameChanged != null) NameChanged(); } }
And then the view implementation which is as minimalistic as possible:
// Parent View public partial class ParentView : Form , IParentView { public ParentView() { InitializeComponent(); }
public ParentPresenter Presenter { private get; set; }
public string Username { set { username.Text = value; } }
void IParentView.Show() { Application.Run(this); }
private void editValueButton_Click(object sender, EventArgs e) { Presenter.EditValue(); } }
// Dialog View public partial class DialogView : Form , IDialogView { public DialogView() { InitializeComponent(); }
public IDialogPresenter Presenter { private get; set; }
public string Username { get { return nameTextBox.Text; } }
void IDialogView.Show() { ShowDialog(); }
void IDialogView.Close() { Close(); }
private void acceptButton_Click(object sender, EventArgs e) { Presenter.EditName(); } }
The way the MVP parts are separated makes a UI with allmost 100% test coverage but above all the UI logic is in a separate class which is not tied to a frame, thus enabling us to discover duplicated code and oportunities to refactor and keep the UI maintainable. I think that this is a great way of driving out a design since I start out with the client hat on and not the other way around were I first list a bunch of methods and properties on a class. IMO this kind of interaction based testing really lends itself to driving out interaction design, and tools like ReSharper really makes the developer experience pleasant and productive.
[1] Jean-Paul Boodhoo. Design Patterns: Model View Presenter [2] Dan Bunea. Model View Presenter - is testing the presenter enough [3] Oren Eini. Rhino Mocks - dynamic mocking framework [4] Michael Feathers. The Humble Dialog Box [5] Martin Fowler. Passive View [6] Martin Fowler. Observer Synchronization [7] JetBrains. ReSharper [8] Jeremy Miller. A Simple Example of the "Humble Dialog Box"
Proceeding with a solution there is no way of changing the implementation of the GregorianCalendar class to get the correct behavior so we have to go about this another way. One is to subclass the GregorianCalendar and override the GetWeekOfYear method. Another is to implement the GetWeekOfYear in a class totally separate from the .NET framework. I think that the first one is the way to go since the error that we're trying to correct is in the framework itself.
So, first we alter the help method in the test case to use our sub classed IsoCalendar (which we haven't written yet).
So, we are not in a compile state yet so lets do the simplest thing to get this running. I decided to subclass the GregorianCalendar class since what is wrong is the GetWeekOfYTear method of that class. I basically override that method like below.
We run the test a get a red bar. Fine, but now lets go ahead and implement the algorithm. However, this has been done over and over with varying elegantness. My favorite is the work of programmer and mathematician Julian Bucknall. His original implementation can be found at his blog. So, instead of returning -1 I call the GetIsoWeek method from Bucknall's implementation and take the modulus of 100 (since the result from the algorithm is of the form YYYYWW). We run the test and we get a green bar!
Now when we get a green bar there's just one more thing to add. The ISO 8601 week should only be returned when the parameters rule and firstDayOfWeek is set properly according to the documentation. In all other cases the GregorianCalendar implementation works just fine. We fix this with a guard clause at the top and we're done.
During this series we covered test coverage for the faulty implementation of weeks according to ISO 8601. We used Test-Driven Development to provide a fix using Julian Bucknall's really smart implementation. Next we should take a look at refactoring to design patterns.
According to the ISO standard, in the period 4 January - 28 December the week number is always the same as the Gregorian week and the same also apply for all Thursdays. Thus, the mentioned dates can be safely excluded in our test coverage. Though we still have an infinite number of dates to cover, we are getting there. Finally, we can limit our test coverage to a set of years that can be reasonable argued to appear in the application which we are implementing.
To simplify it the resulting dates are non Thursdays 1-3 January and 29-31 December every year from 2005 - 2015.
Using the calendar in Outlook I compile a matrix of the week numbers in the year interval. The dates that are grayed are Thursdays which should not be part of the test.
The matrix can be thought of as a set of { date, week number } pairs which can easily be implemented in code.
I create a test which iterates over the set and makes assertions that the correct week was generated by the calendar. It turns out however, that only eleven of the dates generate a wrong week number. I refactor the code to only include the weeks that are wrong. I get a red bar and I see another opportunity for refactoring, the previous two tests can be integrated with this test by just adding the date - week pair to the set. The following is the resulting test:
Now that we have a test that fails we can come up with a solution to get the test to pass.
Abstract So, now we make up another test. Looking at the calendar we see that new years eave 2001 should also belong to the first week of 2002 according to ISO 8601. We write the test much like the previous test and we get another red bar. Now its time to refactor. We need to remove the duplicated code in the two tests. First we start with extract method which results in the following method:
Now, we can refactor the tests using the new method like this:
The implementation of weeks according to ISO 8601 (used e.g. in Sweden) is faulty in .NET Framework. In particular the GregorianCalendar and CultureInfo classes are faulty when it comes to ISO 8601. So, how do we know that the implementation of ISO 8601 is faulty using TDD? We come up with a test that fails. By the ISO definition the first week is the week with the year's first Thursday in it. So, we know that e.g. 2003-12-31 is actually week number 01 of 2004 since it is a Wednesday and thus belongs to the first week. The following is a first attempt at a test: Now we get a red bar and we know that the implementation is flawed. However, this is only a single test. If we get a green bar, is the implementation correct? No, of cource not. We need to write more tests to be sure.