Saturday, December 29, 2007

Playing around with NBehave

As I said recently I'm still exploring tdd and its capabilities. The next evolutionary step could be bdd. Therefore I downloaded NBehave and I tried to write one story with it. Passive View is my preferred playground and thats how it goes with NBehave and TypeMock.NET:

First the declaration of the View, the Presenter and a Service-Gateway that is used by the Presenter to retrieve some information.
protected IView _view;
protected Presenter _presenter;
protected EventHandler _updateRequestedEvent;
protected IServiceGateway _serviceGatway;

The setup of the this objects is not showed here. It simples instantiates mocks for the View and the ServiceGateway and injects it into the Presenter using Constructor-Injection. The _updateRequestedEvent is a mocked event on the view and is also used later in the example.

First I have to specify a story. This is done like that:

[TestFixtureSetUp]
public void FixtureSetup()
{
_getCurrentTimeStory = new Story("Getting the current service time");
_getCurrentTimeStory.AsA("User").IWant("to update the displayed current time")
.SoThat("I can see what time is on the serivce side");
}

And that's one scenario that came in my mind:

[Test]
public void HelloNTServiceIsNotAvailable()
{
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
_view.ShowMessageBox("The Service is currently not available");
recorder.CheckArguments();
}
_getCurrentTimeStory.WithScenario("Service is not available")
.Given("the Service returns an exception", new Exception("Error"), e =>
{
using (RecordExpectations recorder = RecorderManager.StartRecording))
{
recorder.ExpectAndThrow(_serviceGatway.GetTime(), e);
}
})
.When("I update the current time", () => _updateRequestedEvent(this, EventArgs.Empty))
.Then("a message box should display", "The Service is currently not available", m =>
{
MockManager.Verify();
})
;
}

Looks quite chaotic and a developer not used to NUnit,TypeMock and NBehave might not understand it at first glance. I also think the combination of NUnit,TypeMock and NBehave is a little bit strange as they do not integrate very well. Maybe there is another way how to combine those frameworks?

But what I like is the overall structure that it gives to the tests and the readable test output that can be interpreted by a product owner. Here are now the scenario above and another scenario that I could present to him:

Story: Getting the current service time

Narrative:
As a User
I want to update the displayed current time
So that I can see what time is on the serivce side

Scenario 1: Service is not available
Given the Service returns an exception: System.Exception: Error
When I update the current time
Then a message box should display: The Service is currently not available

Scenario 2: Service is available
Given the Service returns the time: 01.01.2000 12:24:23
When I update the current time
Then the label on the view should display: 12:24

Sunday, December 16, 2007

Evaluating a dependency injection framework

I heard the first time about tdd in the year 2002 when a colleague of mine introduced me to a tool called 'NUnit'. I found tdd very helpful from the beginning and I was always one of them that pushed that paradigm and mindset. I learned like a lot of the other tdd enthusiasts, that 'test first' is good, that 'test isolation' is really necessary, that a 'mocking framework' helps a lot, and that it's all about a good design. On this journey I'm now at a point where I question: could a 'dependency injection framework' help?

That is what I tried to find out today and what this post is about. I wrote a simple application including:
  • a wpf client with one window called Window1
  • a wcf service called Service with one Methode GetDate() that returns the current date and time
  • one assembly testing the wpf-presentation and wcf-service (just unit-tests)

Introducing a DI-Framework

One trying to write tests in such an environment knows that integrating the real wpf- and wcf-environment into the tests is a bad idea. Instead it's better to stub and mock those environments to get easier, more stable, and faster tests. This means we usually want a test-configuration where the most external dependencies (like wpf or wcf) are mocks or stubs. On the other hand we want to have a configuration on a deployed system that utilizes the real dependencies. So it's something about configuration and that's where the DI-frameworks come into play.

I decided to give Jeremy's StructureMap a try because it doesn't look so overloaded like Sprint.NET or Windsor.

Following code shows my wcf-service IService that I include in the presentation-layer as a Service-Gateway (see also ServiceStub-Pattern):


[ServiceContract]
public interface IService
{
[OperationContract]
DateTime GetTime();
}
/// <summary>
/// Gateway to intercept for testing
/// </summary>
public interface IServiceGateway : IService
{
void Close();
}
/// <summary>
/// Real gateway using the wcf generated ServiceClient class
/// </summary>
public class ServiceGateway : IServiceGateway
{
private readonly ServiceClient _service;

public ServiceGateway()
{
_service = new ServiceClient();
}

public void Close()
{
_service.Close();
}

public DateTime GetTime()
{
return _service.GetTime();
}
}
/// <summary>
/// Stub for testing
/// </summary>
public class ServiceGatewayStub : IServiceGateway
{
public void Close()
{
}

public DateTime GetTime()
{
return new DateTime(2000, 1, 1, 12, 34, 55, 12);
}
}
Step 1:
Using the following code to resolve the reference to the external wcf-service

IServiceGateway gateway = ObjectFactory.GetInstance<IServiceGateway>()
and using the following configuration for the tests

<StructureMap>
<DefaultInstance PluginType="HelloNTPresentation.IServiceGateway,HelloNTPresentation" PluggedType="HelloNTService.ServiceGatewayStub,HelloNTTests" Scope="Singleton"/>
</StructureMap>
I could wire the code during the tests to the ServiceGatewayStub instead of the real ServiceGateway.

Step 2:
I didn't like that because it meant that we have to setup a configuration for the real (not test) environment like:

<StructureMap>
<DefaultInstance PluginType="HelloNTPresentation.IServiceGateway,HelloNTPresentation" PluggedType="HelloNTPresentation.ServiceGateway,HelloNTPresentation" Scope="Singleton"/>
</StructureMap>
After I have had read how to build an IoC container in 15 lines of code I thought that DI can't be so difficult and I tried to build my own DI-framework. I liked very much that I could configure the DI in the code now and eliminate the file-based configuration:
      ObjectFactory.Register<IServiceGateway>(() => new ServiceGatewayStub());
IServiceGateway gateway = ObjectFactory.Create<IServiceGateway>();
All tests were green and I was happy to start the refactored sample application first time after. But there was big surprise when it crashed. I had forgotten to configure DI for the wcf-service and wpf-service. But where should I put that configuration? Both of them run in some kind of hosted environment and I wasn't able to find a nice place to put that configuration-code. So I realized that it's a little bit harder than I thought to write an own DI-Framework.

Step 3:
Back to StructureMap I found a way to minimize the file-based configuration. The solution was to use the attributes PluginFamily and Pluggable that define default behaviour. In this case the class ServiceGateway is the default implementation of IServiceGateway and there is no need to configure it for the wcf-service and the wpf-client anymore.

    [ServiceContract]
public interface IService
{
[OperationContract]
DateTime GetTime();
}
[PluginFamily("ServiceGateway")]
public interface IServiceGateway : IService
{
}
[Pluggable("ServiceGateway")]
public class ServiceGateway : IServiceGateway
{
}
Step 4:
Now let's have a look to following the presenter (presenter is what is responsible for the presentation-logic):

    public class Presenter: IDisposable
{
readonly IView _view;
readonly IServiceGateway _service;

public Presenter(IView view, IServiceGateway service)
{
_view = view;
_service = service;
}
}
That presenter shows all internal dependencies on its constructor. This enables us to use constructor injection when writing tests with a Mock-Framework (e.g. TypeMock)
     _serviceGatway = RecorderManager.CreateMockedObject<IServiceGateway>();
_view = RecorderManager.CreateMockedObject<IView>();
_presenter = new Presenter(_view, _serviceGatway);
But what's about the others that don't want to bother about providing those dependencies to the constructor? And that's where the DI-framework gets really valueable because it enables us to instantiate concrete classes without providing the needed arguments to the constructor. Following code is from the wpf-client and shows how this is done:

    Presenter presenter = ObjectFactory.FillDependencies<Presenter>();
Just for completeness, I have to mention how I configured IView:

    [PluginFamily("Window1")]
public interface IView
{
}
[Pluggable("Window1")]
public partial class Window1 : Window, IView
{
}
Summary

  • I always used constructor injection but with a DI-framework it gets easier because the client code doesn't need to manage the dependencies anymore.
  • I like StructureMap because it looks simple and it works.

Tuesday, December 11, 2007

Offline data synchronization

I wrote a few days before that it looked like I would get involved in a SOA-project. Today it looks like I will get involved in another project! This new project could have following technical characteristics:
  • said to be a rich-client-project
  • support for offline disconnected scenarios (offline agents)
  • distributed application (Internet, intranet or some kind of private network)
  • integration with a backend system (no idea what kind of interface that would be)

Sounds interesting .... So I bought yesterday something about WPF to update myself with 'state of the art rich client development'.

Maybe the new Microsoft Synch Framework could be interesting in that context too. I watched this and it looks promising. I have to admit that I hate that kind of presentations but it looks that it's flexible and can be extended. I'm not yet sure about that but at least the synch-runtime can be instantiated in a object-oriented manner and that's always a good sign. Would be great if it could be connected to a service instead of a database.

Sunday, December 9, 2007

WCF puts all together

I was supposed to get involved into a SOA-project therefore I started to read about WCF. In the meanwhile it turned out that I might not be involved in that project, however I kept on doing my reading on this issue. I went through the following two books:


  • Pro WCF Practical Microsoft SOA Implementation was a good introduction with a lot of code and examples. I liked it as a brief introduction into how WCF 'feels like'. But I switched to the other book soon after since I got more interested in the overall concepts than in the details.

  • I liked Programming WCF Services because it talks in more details about advanced stuff like Instance Management, Faults, Transactions, Concurrency and Security.

Below is what I think about WCF: I think theres is nothing new but that all comes together in a nice consistent way. WCF helps much if an application is more than a monolithic web or rich-client application. I'd like to mention two personal highlights:


Saturday, December 1, 2007

excpetion handling could be easy

We have been doing a major refactoring in our project trying to get rid of the legacy exception handling. As we went through our code we had some good laughs (we shouldn't have laughed as we still have to maintain that for a long time) and it was obvious that some developers had no clue about how to deal with exceptions or were too lazy to implement a more sophisticated handling. It seemed that some developers didn't miss any opportunity to get rid of that nasty exceptions. It seemed that we were fighting a .NET-bug called 'Exception'.

We also had a lot of discussons about exceptions, especially because we wanted to eliminate exception swallowing but not to change the user experience! Our product manager stated that it's better to have an obscure behaviour that the users knows than a new fancy error dialog that indicates problems at the root. (Users don't like fail fast!)

I didn't want to talk about that stuff but I have just come across some similar thoughts:

http://grabbagoft.blogspot.com/2007/11/stop-madness.html (see Try Catch Publish Swallow)
http://grabbagoft.blogspot.com/2007/06/swallowing-exceptions-is-hazardous-to.html
http://grabbagoft.blogspot.com/2007/06/re-throwing-exceptions.html